├── cloneDeep ├── .gitignore ├── README.md ├── test │ ├── 5.test.js │ ├── clone1.test.js │ ├── 2.test.js │ ├── 3.test.js │ ├── 7.test.js │ ├── 6.test.js │ ├── clone3.test.js │ ├── 4.test.js │ ├── 1.test.js │ ├── clone2.test.js │ ├── clone4.test.js │ └── 8.test.js ├── src │ ├── clone1.js │ ├── clone2.js │ ├── clone3.js │ └── clone4.js ├── package.json └── package-lock.json ├── pnpm ├── 01-npm@2 │ ├── .gitignore │ ├── node_modules │ │ ├── demo-baz │ │ │ ├── index.js │ │ │ ├── node_modules │ │ │ │ └── demo-bar │ │ │ │ │ ├── index.js │ │ │ │ │ └── package.json │ │ │ └── package.json │ │ └── demo-foo │ │ │ ├── index.js │ │ │ ├── node_modules │ │ │ └── demo-bar │ │ │ │ ├── index.js │ │ │ │ └── package.json │ │ │ └── package.json │ ├── README.md │ └── package.json ├── 02-yarn │ ├── .gitignore │ ├── node_modules │ │ ├── demo-bar │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── demo-baz │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── demo-foo │ │ │ ├── index.js │ │ │ └── package.json │ │ └── .yarn-integrity │ ├── README.md │ └── package.json ├── 03-npm-doppelgangers │ ├── .gitignore │ ├── node_modules │ │ ├── demo-bar │ │ │ ├── index.js │ │ │ └── package.json │ │ ├── demo-baz │ │ │ ├── index.js │ │ │ ├── node_modules │ │ │ │ └── demo-bar │ │ │ │ │ ├── index.js │ │ │ │ │ └── package.json │ │ │ └── package.json │ │ ├── demo-foo │ │ │ ├── index.js │ │ │ ├── node_modules │ │ │ │ └── demo-bar │ │ │ │ │ ├── index.js │ │ │ │ │ └── package.json │ │ │ └── package.json │ │ └── .yarn-integrity │ ├── README.md │ └── package.json ├── 00-demos-packages │ ├── demo-bar-1.0.0 │ │ ├── index.js │ │ └── package.json │ ├── demo-bar-1.0.1 │ │ ├── index.js │ │ └── package.json │ ├── demo-baz-1.0.0 │ │ ├── index.js │ │ └── package.json │ ├── demo-foo-1.0.0 │ │ ├── index.js │ │ └── package.json │ └── demo-foo-1.0.1 │ │ ├── index.js │ │ └── package.json └── 04-pnpm │ ├── README.md │ ├── package.json │ └── pnpm-lock.yaml ├── gulp-demo ├── .gitignore ├── dist │ ├── images │ │ ├── 1.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ ├── 9.jpg │ │ ├── 10.jpg │ │ ├── 11.jpg │ │ └── 12.jpg │ ├── rev-manifest.json │ ├── css │ │ ├── public.css │ │ └── public-5c001c53f6.css │ └── index.html ├── src │ ├── images │ │ ├── 1.jpg │ │ ├── 10.jpg │ │ ├── 11.jpg │ │ ├── 12.jpg │ │ ├── 2.jpg │ │ ├── 3.jpg │ │ ├── 4.jpg │ │ ├── 5.jpg │ │ ├── 6.jpg │ │ ├── 7.jpg │ │ ├── 8.jpg │ │ └── 9.jpg │ ├── js │ │ └── myAlbum.js │ ├── css │ │ └── myAlbum.css │ ├── less │ │ └── myAlbum.less │ └── index.html ├── README.md ├── package.json └── gulpfile.js ├── .gitignore ├── browserCache ├── README.md ├── src │ ├── cacheControl.js │ ├── expries.js │ ├── pragma.js │ ├── utils.js │ ├── priority.js │ ├── eTag.js │ └── lastModified.js ├── package.json ├── index.js └── static │ └── index.html ├── lazyLoad ├── loading.jpg ├── README.md └── index.html ├── amplifier ├── Images │ ├── big.jpg │ └── small.jpg ├── README.md └── index.html ├── vueDataBind ├── README.md ├── index.html └── Vue.js ├── promise ├── README.md ├── test │ ├── promise3.test.js │ ├── promise4.test.js │ ├── promise1.test.js │ ├── promise2.test.js │ └── promise5.test.js ├── package.json ├── src │ ├── promise1.js │ ├── promise2.js │ ├── promise3.js │ ├── promise4.js │ └── promise5.js └── package-lock.json ├── typescript ├── README.md ├── package.json ├── tsconfig.json ├── 03-sample.ts ├── 04-sample.ts ├── 01-sample.ts ├── 02-sample.ts └── yarn.lock └── README.md /cloneDeep/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /pnpm/01-npm@2/.gitignore: -------------------------------------------------------------------------------- 1 | !node_modules -------------------------------------------------------------------------------- /pnpm/02-yarn/.gitignore: -------------------------------------------------------------------------------- 1 | !node_modules -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/.gitignore: -------------------------------------------------------------------------------- 1 | !node_modules -------------------------------------------------------------------------------- /gulp-demo/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | package-lock.json -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | yarn-error.log 3 | npm-debug.log -------------------------------------------------------------------------------- /pnpm/02-yarn/node_modules/demo-bar/index.js: -------------------------------------------------------------------------------- 1 | 2 | console.log('bar') -------------------------------------------------------------------------------- /pnpm/00-demos-packages/demo-bar-1.0.0/index.js: -------------------------------------------------------------------------------- 1 | 2 | console.log('bar') -------------------------------------------------------------------------------- /pnpm/00-demos-packages/demo-bar-1.0.1/index.js: -------------------------------------------------------------------------------- 1 | 2 | console.log('bar') -------------------------------------------------------------------------------- /browserCache/README.md: -------------------------------------------------------------------------------- 1 | ## step 2 | 3 | - `npm install` 4 | - `npm start` 5 | 6 | -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/demo-bar/index.js: -------------------------------------------------------------------------------- 1 | 2 | console.log('bar') -------------------------------------------------------------------------------- /pnpm/01-npm@2/node_modules/demo-baz/index.js: -------------------------------------------------------------------------------- 1 | require('demo-bar') 2 | console.log('baz') -------------------------------------------------------------------------------- /pnpm/02-yarn/node_modules/demo-baz/index.js: -------------------------------------------------------------------------------- 1 | require('demo-bar') 2 | console.log('baz') -------------------------------------------------------------------------------- /lazyLoad/loading.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/lazyLoad/loading.jpg -------------------------------------------------------------------------------- /pnpm/00-demos-packages/demo-baz-1.0.0/index.js: -------------------------------------------------------------------------------- 1 | require('demo-bar') 2 | console.log('baz') -------------------------------------------------------------------------------- /pnpm/00-demos-packages/demo-foo-1.0.0/index.js: -------------------------------------------------------------------------------- 1 | require('example-bar') 2 | console.log('foo') -------------------------------------------------------------------------------- /pnpm/00-demos-packages/demo-foo-1.0.1/index.js: -------------------------------------------------------------------------------- 1 | require('demo-bar') 2 | console.log('foo') -------------------------------------------------------------------------------- /pnpm/01-npm@2/node_modules/demo-baz/node_modules/demo-bar/index.js: -------------------------------------------------------------------------------- 1 | 2 | console.log('bar') -------------------------------------------------------------------------------- /pnpm/01-npm@2/node_modules/demo-foo/index.js: -------------------------------------------------------------------------------- 1 | require('example-bar') 2 | console.log('foo') -------------------------------------------------------------------------------- /pnpm/01-npm@2/node_modules/demo-foo/node_modules/demo-bar/index.js: -------------------------------------------------------------------------------- 1 | 2 | console.log('bar') -------------------------------------------------------------------------------- /pnpm/02-yarn/node_modules/demo-foo/index.js: -------------------------------------------------------------------------------- 1 | require('example-bar') 2 | console.log('foo') -------------------------------------------------------------------------------- /amplifier/Images/big.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/amplifier/Images/big.jpg -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/demo-baz/index.js: -------------------------------------------------------------------------------- 1 | require('demo-bar') 2 | console.log('baz') -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/demo-baz/node_modules/demo-bar/index.js: -------------------------------------------------------------------------------- 1 | 2 | console.log('bar') -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/demo-foo/index.js: -------------------------------------------------------------------------------- 1 | require('example-bar') 2 | console.log('foo') -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/demo-foo/node_modules/demo-bar/index.js: -------------------------------------------------------------------------------- 1 | 2 | console.log('bar') -------------------------------------------------------------------------------- /amplifier/Images/small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/amplifier/Images/small.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/1.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/2.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/3.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/4.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/5.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/6.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/7.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/8.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/9.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/1.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/10.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/11.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/12.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/2.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/3.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/4.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/5.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/6.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/7.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/8.jpg -------------------------------------------------------------------------------- /gulp-demo/src/images/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/src/images/9.jpg -------------------------------------------------------------------------------- /lazyLoad/README.md: -------------------------------------------------------------------------------- 1 | # lazyLoad 2 | 3 | - [image lazyload demo](https://lvqq.github.io/blog-samples/lazyLoad/) -------------------------------------------------------------------------------- /gulp-demo/dist/images/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/10.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/11.jpg -------------------------------------------------------------------------------- /gulp-demo/dist/images/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lvqq/blog-samples/HEAD/gulp-demo/dist/images/12.jpg -------------------------------------------------------------------------------- /vueDataBind/README.md: -------------------------------------------------------------------------------- 1 | # vueDataBind 2 | 3 | - [Vue bind demo](https://lvqq.github.io/blog-samples/vueDataBind/) -------------------------------------------------------------------------------- /pnpm/01-npm@2/README.md: -------------------------------------------------------------------------------- 1 | # Steps 2 | 3 | 1. Use Nodejs 4.9.1, for example: `nvm use 4.9.1` 4 | 2. Run `npm install` -------------------------------------------------------------------------------- /pnpm/04-pnpm/README.md: -------------------------------------------------------------------------------- 1 | # Steps 2 | 3 | 1. Install `pnpm`, run `npm install -g pnpm` 4 | 2. Run `pnpm install` 5 | -------------------------------------------------------------------------------- /gulp-demo/dist/rev-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "public.css": "public-5c001c53f6.css", 3 | "public.js": "public-93c275a836.js" 4 | } -------------------------------------------------------------------------------- /promise/README.md: -------------------------------------------------------------------------------- 1 | # promise 2 | 3 | - [how to implement a promise](https://www.chlorine.site/posts/2020/04/01/_06-promise.html) 4 | -------------------------------------------------------------------------------- /cloneDeep/README.md: -------------------------------------------------------------------------------- 1 | # cloneDeep 2 | 3 | - [implement cloneDeep](https://www.nicksonlvqq.cn/blogs/posts/2019/09/16/_06-clonedeep.html) 4 | -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/README.md: -------------------------------------------------------------------------------- 1 | # Steps 2 | 3 | 1. Install `yarn`, run `npm install -g yarn` 4 | 2. Run `yarn --no-lockfile` 5 | -------------------------------------------------------------------------------- /gulp-demo/README.md: -------------------------------------------------------------------------------- 1 | # gulp-demo 2 | - [implement font-end automation by using gulp](https://www.chlorine.site/posts/2018/11/22/_01-gulp.html) -------------------------------------------------------------------------------- /cloneDeep/test/5.test.js: -------------------------------------------------------------------------------- 1 | // 循环引用,验证栈溢出 2 | const cloneDeep = require('../src/clone2') 3 | 4 | const a = {} 5 | a.a = a 6 | 7 | cloneDeep(a) 8 | -------------------------------------------------------------------------------- /browserCache/src/cacheControl.js: -------------------------------------------------------------------------------- 1 | module.exports = (req, res) => { 2 | res.setHeader('Cache-Control', 'public,max-age=10') 3 | res.end('ok') 4 | } 5 | -------------------------------------------------------------------------------- /pnpm/02-yarn/README.md: -------------------------------------------------------------------------------- 1 | # Steps 2 | 3 | Use `yarn` or `npm@3+` 4 | 5 | 1. Install `yarn`, run `npm install -g yarn` 6 | 2. Run `yarn install --no-lockfile` 7 | -------------------------------------------------------------------------------- /browserCache/src/expries.js: -------------------------------------------------------------------------------- 1 | const { getGMT } = require('./utils') 2 | 3 | module.exports = (req, res) => { 4 | res.setHeader('Expires', getGMT(10)); 5 | res.end('ok'); 6 | } 7 | -------------------------------------------------------------------------------- /amplifier/README.md: -------------------------------------------------------------------------------- 1 | # amplifier 2 | 3 | - [amplifier demo](https://lvqq.github.io/blog-samples/amplifier/) 4 | - [implement a amplifier](https://www.nicksonlvqq.cn/blogs/posts/2017/12/06/_01-amplifier.html) -------------------------------------------------------------------------------- /pnpm/02-yarn/node_modules/demo-bar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-bar", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC" 11 | } 12 | -------------------------------------------------------------------------------- /pnpm/00-demos-packages/demo-bar-1.0.0/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-bar", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC" 11 | } 12 | -------------------------------------------------------------------------------- /pnpm/00-demos-packages/demo-bar-1.0.1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-bar", 3 | "version": "1.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC" 11 | } 12 | -------------------------------------------------------------------------------- /cloneDeep/test/clone1.test.js: -------------------------------------------------------------------------------- 1 | // 简单深拷贝验证 2 | const cloneDeep = require('../src/clone1') 3 | 4 | const data = { 5 | str: 'test', 6 | obj: { 7 | foo: 'test' 8 | }, 9 | arr: ['test', {foo: 'test'}] 10 | } 11 | 12 | const dataCopy = cloneDeep(data) 13 | 14 | console.log('dataCopy:\n', dataCopy) 15 | -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/demo-bar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-bar", 3 | "version": "1.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC" 11 | } 12 | -------------------------------------------------------------------------------- /cloneDeep/src/clone1.js: -------------------------------------------------------------------------------- 1 | // 简单深拷贝 2 | function cloneDeep(data) { 3 | if(!data || typeof data !== 'object') return data 4 | const retVal = Array.isArray(data) ? [] : {} 5 | for(let key in data) { 6 | retVal[key] = cloneDeep(data[key]) 7 | } 8 | return retVal 9 | } 10 | 11 | module.exports = cloneDeep 12 | -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/demo-baz/node_modules/demo-bar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-bar", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC" 11 | } 12 | -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/demo-foo/node_modules/demo-bar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-bar", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC" 11 | } 12 | -------------------------------------------------------------------------------- /cloneDeep/test/2.test.js: -------------------------------------------------------------------------------- 1 | // 验证 JSON.parse(JSON.stringify(data)) 2 | // 当 data 的子数据为基本类型 3 | const data = { 4 | a: 1, 5 | b: 'str', 6 | c: true, 7 | d: null, 8 | e: undefined, 9 | f: NaN, 10 | g: Infinity, 11 | } 12 | 13 | const dataCopy = JSON.parse(JSON.stringify(data)) 14 | 15 | console.log('dataCopy:\n', dataCopy) 16 | -------------------------------------------------------------------------------- /typescript/README.md: -------------------------------------------------------------------------------- 1 | # TypeScript 2 | [TypeScript Summary](https://www.chlorine.site/posts/2022/08/22/_08-typescript.html) 3 | 4 | # Usage 5 | 6 | Enter `typescript` directory and install 7 | ```bash 8 | yarn 9 | ``` 10 | 11 | Run `ts-node` scripts: 12 | ```bash 13 | yarn tsc1 14 | 15 | yarn tsc2 16 | 17 | yarn tsc3 18 | 19 | yarn tsc4 20 | ``` -------------------------------------------------------------------------------- /promise/test/promise3.test.js: -------------------------------------------------------------------------------- 1 | const MyPromise = require('../src/promise3') 2 | 3 | const promise = new MyPromise((resolve) => { 4 | setTimeout(() => { 5 | resolve(1) 6 | }, 100) 7 | }) 8 | 9 | promise.then((value) => { 10 | console.log('value1', value); 11 | return 2 12 | }) 13 | .then((value) => { 14 | console.log('value2', value); 15 | }) -------------------------------------------------------------------------------- /browserCache/src/pragma.js: -------------------------------------------------------------------------------- 1 | // pragma 请求头部 2 | exports.request = (req, res) => { 3 | res.setHeader('Cache-Control', 'public,max-age=1000') 4 | res.end('ok') 5 | } 6 | 7 | // pragma 响应头部 8 | exports.response = (req, res) => { 9 | res.setHeader('Pragma', 'no-cache') 10 | // res.setHeader('Cache-Control', 'public,max-age=1000') 11 | res.end('ok') 12 | } -------------------------------------------------------------------------------- /pnpm/02-yarn/node_modules/demo-baz/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-baz", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-bar": "1.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /pnpm/02-yarn/node_modules/demo-foo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-foo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-bar": "1.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /promise/test/promise4.test.js: -------------------------------------------------------------------------------- 1 | // 运行 npm run test4 进行测试 2 | const MyPromise = require('../src/promise4') 3 | 4 | MyPromise.defer = MyPromise.deferred = () => { 5 | let d = {} 6 | d.promise = new MyPromise((resolve, reject) => { 7 | d.resolve = resolve; 8 | d.reject = reject; 9 | }); 10 | return d; 11 | } 12 | 13 | module.exports = MyPromise 14 | -------------------------------------------------------------------------------- /pnpm/00-demos-packages/demo-baz-1.0.0/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-baz", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-bar": "1.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /pnpm/00-demos-packages/demo-foo-1.0.0/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-foo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-bar": "1.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /pnpm/00-demos-packages/demo-foo-1.0.1/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-foo", 3 | "version": "1.0.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-bar": "1.0.1" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /pnpm/01-npm@2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-baz": "1.0.0", 13 | "demo-foo": "1.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /pnpm/02-yarn/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-foo": "1.0.0", 13 | "demo-baz": "1.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /pnpm/04-pnpm/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-foo": "1.0.1", 13 | "demo-baz": "1.0.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/demo-baz/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-baz", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-bar": "1.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/demo-foo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-foo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-bar": "1.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /cloneDeep/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "clonedeep", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "jquery": "^3.4.1", 13 | "jsdom": "^15.1.1", 14 | "loadsh": "0.0.4" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /browserCache/src/utils.js: -------------------------------------------------------------------------------- 1 | const moment = require('moment'); 2 | const crypto = require('crypto'); 3 | 4 | // GMT 格式时间转化 5 | exports.getGMT = (second = 10) => `${moment().utc().add(second, 's').format('ddd, DD MMM YYYY HH:mm:ss')} GMT`; 6 | 7 | // 创建 md5 加密 8 | exports.cryptoFile = (file) => { 9 | const md5 = crypto.createHash('md5'); 10 | return md5.update(file).digest('hex'); 11 | } 12 | -------------------------------------------------------------------------------- /cloneDeep/test/3.test.js: -------------------------------------------------------------------------------- 1 | // 验证 JSON.parse(JSON.stringify(data)) 2 | // 当 data 的子数据为引用类型 3 | const data = { 4 | a: [1, 2, 3], 5 | b: {foo: 'obj'}, 6 | c: new Date('2019-08-28'), 7 | d: /^abc$/g, 8 | e: function() {}, 9 | f: new Set([1, 2, 3]), 10 | g: new Map([['foo', 'map']]), 11 | } 12 | 13 | const dataCopy = JSON.parse(JSON.stringify(data)) 14 | 15 | console.log('dataCopy:\n', dataCopy) 16 | -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-foo": "1.0.0", 13 | "demo-baz": "1.0.0", 14 | "demo-bar": "1.0.1" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /cloneDeep/test/7.test.js: -------------------------------------------------------------------------------- 1 | // 验证层级过深递归栈溢出 2 | const cloneDeep = require('../src/clone3') 3 | 4 | function create(depth, breadth) { 5 | const data = {} 6 | let temp = data 7 | let i = j = 0 8 | while(i < depth) { 9 | temp = temp['data'] = {} 10 | while(j < breadth) { 11 | temp[j] = j 12 | j++ 13 | } 14 | i++ 15 | } 16 | return data 17 | } 18 | 19 | const data = create(10000, 100) 20 | 21 | console.log(cloneDeep(data)) -------------------------------------------------------------------------------- /typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "typescript", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "tsc1": "ts-node 01-sample", 8 | "tsc2": "ts-node 02-sample", 9 | "tsc3": "ts-node 03-sample", 10 | "tsc4": "ts-node 04-sample" 11 | }, 12 | "author": "", 13 | "license": "ISC", 14 | "devDependencies": { 15 | "typescript": "^4.7.4", 16 | "ts-node": "^10.9.1" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /promise/test/promise1.test.js: -------------------------------------------------------------------------------- 1 | const MyPromise = require('../src/promise1') 2 | 3 | // 同步 4 | const promise1 = new MyPromise((resolve, reject) => { 5 | resolve(1) 6 | }) 7 | 8 | promise1.then((value) => { 9 | console.log('value1', value) 10 | }) 11 | 12 | // 异步 13 | const promise2 = new MyPromise((resolve, reject) => { 14 | setTimeout(() => { 15 | resolve(1) 16 | }, 2000) 17 | }) 18 | 19 | promise2.then((value) => { 20 | console.log('value2', value) 21 | }) -------------------------------------------------------------------------------- /promise/test/promise2.test.js: -------------------------------------------------------------------------------- 1 | const MyPromise = require('../src/promise2') 2 | 3 | // 同步 4 | const promise1 = new MyPromise((resolve, reject) => { 5 | resolve(1) 6 | }) 7 | 8 | promise1.then((value) => { 9 | console.log('value1', value) 10 | }) 11 | 12 | // 异步 13 | const promise2 = new MyPromise((resolve, reject) => { 14 | setTimeout(() => { 15 | resolve(1) 16 | }, 2000) 17 | }) 18 | 19 | promise2.then((value) => { 20 | console.log('value2', value) 21 | }) -------------------------------------------------------------------------------- /browserCache/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "browsercache", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon index.js", 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "express": "^4.17.1", 14 | "moment": "^2.24.0" 15 | }, 16 | "devDependencies": { 17 | "nodemon": "^2.0.2" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /browserCache/src/priority.js: -------------------------------------------------------------------------------- 1 | // 优先级 2 | const { getGMT } = require('./utils') 3 | 4 | // Pragma > Cache-Control 5 | exports.priority1 = (req, res) => { 6 | res.setHeader('Pragma', 'no-cache'); 7 | res.setHeader('Cache-Control', 'public,max-age=1000'); 8 | res.end('ok'); 9 | } 10 | 11 | // Cache-Control > Expries 12 | exports.priority2 = (req, res) => { 13 | res.setHeader('Cache-Control', 'no-cache'); 14 | res.setHeader('Expries', getGMT(1000)) 15 | res.end('ok'); 16 | } 17 | -------------------------------------------------------------------------------- /cloneDeep/test/6.test.js: -------------------------------------------------------------------------------- 1 | // 循环引用 验证解除引用 2 | const cloneDeep = require('../src/clone2') 3 | 4 | const temp = {} 5 | const data = { 6 | a: temp, 7 | b: temp, 8 | } 9 | const dataJson = JSON.parse(JSON.stringify(data)) 10 | const dataClone = cloneDeep(data) 11 | 12 | // 验证对于其他数据的引用关系 13 | console.log('data.a === data.b: ', data.a === data.b) 14 | console.log('dataJson.a === dataJson.b: ', dataJson.a === dataJson.b) 15 | console.log('dataClone.a === dataClone.b: ', dataClone.a === dataClone.b) -------------------------------------------------------------------------------- /promise/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "promise", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "test1": "node ./test/promise1.test.js", 11 | "test2": "node ./test/promise2.test.js", 12 | "test3": "node ./test/promise3.test.js", 13 | "test4": "promises-aplus-tests ./test/promise4.test.js", 14 | "test5": "node ./test/promise5.test.js" 15 | }, 16 | "author": "", 17 | "license": "ISC", 18 | "devDependencies": { 19 | "promises-aplus-tests": "^2.1.2" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /browserCache/src/eTag.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const { cryptoFile } = require('./utils') 4 | 5 | const filePath = path.join(__dirname, '../static/index.html') 6 | 7 | module.exports = (req, res) => { 8 | const file = fs.readFileSync(filePath); 9 | const eTag = cryptoFile(file) 10 | 11 | res.setHeader('Cache-Control', 'public,max-age=10'); 12 | 13 | if (eTag === req.headers['if-none-match']) { 14 | res.writeHead(304, 'Not Modified'); 15 | res.end(); 16 | } else { 17 | res.setHeader('ETag', eTag); 18 | res.writeHead(200, 'OK'); 19 | res.end(file); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /browserCache/src/lastModified.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | 4 | const filePath = path.join(__dirname, '../static/index.html') 5 | 6 | module.exports = (req, res) => { 7 | const stat = fs.statSync(filePath); 8 | const file = fs.readFileSync(filePath); 9 | const lastModified = stat.mtime.toUTCString(); 10 | 11 | res.setHeader('Cache-Control', 'public,max-age=10'); 12 | 13 | if (lastModified === req.headers['if-modified-since']) { 14 | res.writeHead(304, 'Not Modified'); 15 | res.end(); 16 | } else { 17 | res.setHeader('Last-Modified', lastModified); 18 | res.writeHead(200, 'OK'); 19 | res.end(file); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /cloneDeep/test/clone3.test.js: -------------------------------------------------------------------------------- 1 | // 验证循环引用 2 | const cloneDeep = require('../src/clone3') 3 | 4 | const temp = {} 5 | const data = { 6 | a: temp, 7 | b: temp, 8 | } 9 | const dataClone = cloneDeep(data) 10 | 11 | const obj = {} 12 | obj.obj = obj 13 | 14 | const arr = [] 15 | arr[0] = arr 16 | 17 | const set = new Set() 18 | set.add(set) 19 | 20 | const map = new Map() 21 | map.set(map, map) 22 | 23 | // 验证引用关系 24 | console.log('dataClone.a === dataClone.b: ', dataClone.a === dataClone.b) // true 25 | 26 | // 验证环 27 | console.log('obj:\n', cloneDeep(obj)) 28 | console.log('arr:\n', cloneDeep(arr)) 29 | console.log('set:\n', cloneDeep(set)) 30 | console.log('map:\n', cloneDeep(map)) 31 | -------------------------------------------------------------------------------- /cloneDeep/test/4.test.js: -------------------------------------------------------------------------------- 1 | // 验证 JSON.parse(JSON.stringify(data)) 2 | // 当 data 为自定义构造函数的实例对象 3 | 4 | function Person(name) { 5 | // 构造函数实例属性name 6 | this.name = name 7 | // 构造函数实例方法getName 8 | this.getName = function () { 9 | return this.name 10 | } 11 | } 12 | // 构造函数原型属性age 13 | Person.prototype.age = 18 14 | 15 | const person = new Person('xxx') 16 | const personCopy = JSON.parse(JSON.stringify(person)) 17 | 18 | console.log('person: ', person) 19 | console.log('personCopy: ', personCopy) 20 | console.log('person.age: ', person.age) 21 | console.log('personCopy.age: ', personCopy.age) 22 | console.log('person.constructor:\n', person.constructor) 23 | console.log('personCopy.constructor:\n', personCopy.constructor) 24 | -------------------------------------------------------------------------------- /cloneDeep/test/1.test.js: -------------------------------------------------------------------------------- 1 | // 验证原生浅拷贝方法 2 | const arr = ['test', { foo: 'test' }] 3 | 4 | const obj = { 5 | str: 'test', 6 | obj: { 7 | foo: 'test' 8 | } 9 | } 10 | 11 | const arr1 = arr.slice() 12 | const arr2 = arr.concat() 13 | const arr3 = Array.from(arr) 14 | const arr4 = [...arr] 15 | 16 | const obj1 = Object.assign({}, obj) 17 | const obj2 = {...obj} 18 | 19 | //修改arr 20 | arr[0] = 'test1' 21 | arr[1].foo = 'test1' 22 | // 修改obj 23 | obj.str = 'test1' 24 | obj.obj.foo = 'test1' 25 | 26 | //验证引用关系 27 | console.log('arr: ', arr) 28 | console.log('arr1: ', arr1) 29 | console.log('arr2: ', arr2) 30 | console.log('arr3: ', arr3) 31 | console.log('arr4: ', arr4) 32 | console.log('obj: ', obj) 33 | console.log('obj1: ', obj1) 34 | console.log('obj2: ', obj2) 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Samples 2 | - [Pnpm](https://github.com/lvqq/blog-samples/tree/master/pnpm) 3 | - [TypeScript](https://github.com/lvqq/blog-samples/tree/master/typescript) 4 | - [Vue data-bind](https://github.com/lvqq/blog-samples/tree/master/vueDataBind) 5 | - [Promise](https://github.com/lvqq/blog-samples/tree/master/promise) 6 | - [Browser cache](https://github.com/lvqq/blog-samples/tree/master/browserCache) 7 | - [CloneDeep](https://github.com/lvqq/blog-samples/tree/master/cloneDeep) 8 | - [Gulp](https://github.com/lvqq/blog-samples/tree/master/gulp-demo) 9 | - [Lazyload](https://github.com/lvqq/blog-samples/tree/master/lazyLoad) 10 | - [Amplifier](https://github.com/lvqq/blog-samples/tree/master/amplifier) 11 | 12 | ## Blog Repository 13 | - [Blogs](https://github.com/lvqq/blog) 14 | -------------------------------------------------------------------------------- /pnpm/02-yarn/node_modules/.yarn-integrity: -------------------------------------------------------------------------------- 1 | { 2 | "systemParams": "win32-x64-83", 3 | "modulesFolders": [ 4 | "node_modules" 5 | ], 6 | "flags": [], 7 | "linkedModules": [ 8 | "@oyo\\aries", 9 | "aries", 10 | "yarn" 11 | ], 12 | "topLevelPatterns": [ 13 | "demo-baz@1.0.0", 14 | "demo-foo@1.0.0" 15 | ], 16 | "lockfileEntries": { 17 | "demo-bar@1.0.0": "https://registry.yarnpkg.com/demo-bar/-/demo-bar-1.0.0.tgz#842e7e2c482ade053a886a38b8bebd9d47356c7b", 18 | "demo-baz@1.0.0": "https://registry.yarnpkg.com/demo-baz/-/demo-baz-1.0.0.tgz#0ce32889e87a71064481fa3504274fee5b46983c", 19 | "demo-foo@1.0.0": "https://registry.yarnpkg.com/demo-foo/-/demo-foo-1.0.0.tgz#53a114df5a7cdd0137fb68b01f0a6f0882d0c6b3" 20 | }, 21 | "files": [], 22 | "artifacts": {} 23 | } -------------------------------------------------------------------------------- /vueDataBind/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 双向绑定demo 7 | 8 | 9 |
10 | 姓名:{{ name }} 11 |
请输入姓名
12 | 年龄 {{ age }} 13 |
14 | 15 |
16 |
17 | 18 | 19 | 32 | 33 | -------------------------------------------------------------------------------- /gulp-demo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-demo", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "build": "gulp clean && gulp revision && gulp build && echo \"Sever Build Success ...\"" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "devDependencies": { 12 | "gulp": "^3.9.1", 13 | "gulp-clean": "^0.4.0", 14 | "gulp-concat": "^2.6.1", 15 | "gulp-connect": "^5.6.1", 16 | "gulp-csso": "^3.0.1", 17 | "gulp-if": "^2.0.2", 18 | "gulp-imagemin": "^5.0.3", 19 | "gulp-jshint": "^2.1.0", 20 | "gulp-less": "^4.0.1", 21 | "gulp-rev": "^9.0.0", 22 | "gulp-rev-replace": "^0.4.4", 23 | "gulp-uglify": "^3.0.1", 24 | "gulp-useref": "^3.1.6", 25 | "jshint": "^2.9.6" 26 | }, 27 | "dependencies": {}, 28 | "description": "" 29 | } 30 | -------------------------------------------------------------------------------- /browserCache/index.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs'); 2 | const path = require('path'); 3 | const express = require('express'); 4 | const pragma = require('./src/pragma'); 5 | const priority = require('./src/priority'); 6 | 7 | const app = express(); 8 | const port = 2200; 9 | 10 | app.get('/', (req, res) => res.end(fs.readFileSync(path.join(__dirname, './static/index.html')))); 11 | 12 | app.get('/expries', require('./src/expries')); 13 | app.get('/cacheControl', require('./src/cacheControl')); 14 | app.get('/lastModified', require('./src/lastModified')); 15 | app.get('/eTag', require('./src/eTag')); 16 | 17 | app.get('/pragmaRequest', pragma.request); 18 | app.get('/pragmaResponse', pragma.response); 19 | 20 | app.get('/priority1', priority.priority1) 21 | app.get('/priority2', priority.priority2) 22 | 23 | app.listen(port, () => { 24 | console.log(`server running on port ${port}!`); 25 | }) 26 | -------------------------------------------------------------------------------- /pnpm/03-npm-doppelgangers/node_modules/.yarn-integrity: -------------------------------------------------------------------------------- 1 | { 2 | "systemParams": "win32-x64-83", 3 | "modulesFolders": [ 4 | "node_modules" 5 | ], 6 | "flags": [], 7 | "linkedModules": [ 8 | "@oyo\\aries", 9 | "aries", 10 | "yarn" 11 | ], 12 | "topLevelPatterns": [ 13 | "demo-bar@1.0.1", 14 | "demo-baz@1.0.0", 15 | "demo-foo@1.0.0" 16 | ], 17 | "lockfileEntries": { 18 | "demo-bar@1.0.0": "https://registry.yarnpkg.com/demo-bar/-/demo-bar-1.0.0.tgz#842e7e2c482ade053a886a38b8bebd9d47356c7b", 19 | "demo-bar@1.0.1": "https://registry.yarnpkg.com/demo-bar/-/demo-bar-1.0.1.tgz#d52167539f54d515f1830b0313669cbcbac1f66a", 20 | "demo-baz@1.0.0": "https://registry.yarnpkg.com/demo-baz/-/demo-baz-1.0.0.tgz#0ce32889e87a71064481fa3504274fee5b46983c", 21 | "demo-foo@1.0.0": "https://registry.yarnpkg.com/demo-foo/-/demo-foo-1.0.0.tgz#53a114df5a7cdd0137fb68b01f0a6f0882d0c6b3" 22 | }, 23 | "files": [], 24 | "artifacts": {} 25 | } -------------------------------------------------------------------------------- /pnpm/04-pnpm/pnpm-lock.yaml: -------------------------------------------------------------------------------- 1 | lockfileVersion: 5.4 2 | 3 | specifiers: 4 | demo-baz: 1.0.0 5 | demo-foo: 1.0.1 6 | 7 | dependencies: 8 | demo-baz: 1.0.0 9 | demo-foo: 1.0.1 10 | 11 | packages: 12 | 13 | /demo-bar/1.0.0: 14 | resolution: {integrity: sha512-M32T7z7T8L6+YNWtLhWi2Cul7K6U5yAziWME2fhPHX36XWFUdVyCy6PJD3XdFBKy0cacfWSfEJTWmBkB5f4iEw==} 15 | dev: false 16 | 17 | /demo-bar/1.0.1: 18 | resolution: {integrity: sha512-lz5T/6ZnugMaiiG60H0vDuCcPtIu7HNF4Q9MQHXoqYRno0NSgR7MLRrGtNwFZ584XKix/pV+a0nWBOE8LdAajQ==} 19 | dev: false 20 | 21 | /demo-baz/1.0.0: 22 | resolution: {integrity: sha512-Q5WJf+3qk2kZ+wV8Y+EiJNqN9uATjfSR29Ml7HUMLFSoGP/OeG8MYe3lvlEmidmE5GKBAszzCW5wUVJU3t5RQg==} 23 | dependencies: 24 | demo-bar: 1.0.0 25 | dev: false 26 | 27 | /demo-foo/1.0.1: 28 | resolution: {integrity: sha512-fnUHFEsantdtmml6hBlskQ156CVbe2XXPMT9ec80E2ja597yxcK25Z53qb4pfGGLoLzWWr9MRT/6WG2IfGjS6g==} 29 | dependencies: 30 | demo-bar: 1.0.1 31 | dev: false 32 | -------------------------------------------------------------------------------- /cloneDeep/test/clone2.test.js: -------------------------------------------------------------------------------- 1 | // 验证其他数据类型处理 2 | const cloneDeep = require('../src/clone2') 3 | 4 | const data = { 5 | obj: {}, 6 | arr: [], 7 | reg: /reg/g, 8 | date: new Date('2019'), 9 | person: new Person('xxx'), 10 | set: new Set([{foo: 'set'}]), 11 | map: new Map([[{key: 'map'}, {value: 'map'}]]) 12 | } 13 | 14 | function Person(name) { 15 | this.name = name 16 | } 17 | 18 | const dataClone = cloneDeep(data) 19 | 20 | console.log('dataClone:\n', dataClone) 21 | 22 | // 比较引用地址 23 | console.log(data.obj === dataClone.obj) // false 24 | console.log(data.arr === dataClone.arr) // false 25 | console.log(data.reg === dataClone.reg) // false 26 | console.log(data.date === dataClone.date) // false 27 | console.log(data.func === dataClone.func) // true 28 | console.log([...data.set][0] === [...dataClone.set][0]) // false 29 | console.log([...data.map.keys()][0] === [...dataClone.map.keys()][0]) // false 30 | console.log([...data.map.values()][0] === [...dataClone.map.values()][0]) // false 31 | -------------------------------------------------------------------------------- /promise/src/promise1.js: -------------------------------------------------------------------------------- 1 | // 基本实现 2 | 3 | const STATE = { 4 | PENDING: 'pending', 5 | FULFILLED: 'fulfilled', 6 | REJECTED: 'rejected' 7 | } 8 | 9 | class MyPromise { 10 | constructor(fn) { 11 | // 初始化 12 | this.state = STATE.PENDING 13 | this.value = null 14 | this.reason = null 15 | 16 | // 成功 17 | const fulfill = (value) => { 18 | // 只有 state 为 pending 时,才可以更改状态 19 | if (this.state === STATE.PENDING) { 20 | this.state = STATE.FULFILLED 21 | this.value = value 22 | } 23 | } 24 | 25 | // 失败 26 | const reject = (reason) => { 27 | if (this.state === STATE.PENDING) { 28 | this.state = STATE.REJECTED 29 | this.reason = reason 30 | } 31 | } 32 | // 执行函数出错时调用 reject 33 | try { 34 | fn(fulfill, reject) 35 | } catch (e) { 36 | reject(e) 37 | } 38 | } 39 | 40 | then(onFulfilled, onRejected) { 41 | if (this.state === STATE.FULFILLED) { 42 | onFulfilled(this.value) 43 | } 44 | if (this.state === STATE.REJECTED) { 45 | onRejected(this.reason) 46 | } 47 | } 48 | } 49 | 50 | module.exports = MyPromise -------------------------------------------------------------------------------- /promise/src/promise2.js: -------------------------------------------------------------------------------- 1 | // 解决异步 2 | 3 | const STATE = { 4 | PENDING: 'pending', 5 | FULFILLED: 'fulfilled', 6 | REJECTED: 'rejected' 7 | } 8 | 9 | class MyPromise { 10 | constructor(fn) { 11 | // 初始化 12 | this.state = STATE.PENDING 13 | this.value = null 14 | this.reason = null 15 | // 保存数组 16 | this.fulfilledCallbacks = [] 17 | this.rejectedCallbacks = [] 18 | // 成功 19 | const fulfill = (value) => { 20 | // 只有 state 为 pending 时,才可以更改状态 21 | if (this.state === STATE.PENDING) { 22 | this.state = STATE.FULFILLED 23 | this.value = value 24 | this.fulfilledCallbacks.forEach(cb => cb()) 25 | } 26 | } 27 | 28 | // 失败 29 | const reject = (reason) => { 30 | if (this.state === STATE.PENDING) { 31 | this.state = STATE.REJECTED 32 | this.reason = reason 33 | this.rejectedCallbacks.forEach(cb => cb()) 34 | } 35 | } 36 | // 执行函数出错时调用 reject 37 | try { 38 | fn(fulfill, reject) 39 | } catch (e) { 40 | reject(e) 41 | } 42 | } 43 | 44 | then(onFulfilled, onRejected) { 45 | if (this.state === STATE.FULFILLED) { 46 | onFulfilled(this.value) 47 | } 48 | if (this.state === STATE.REJECTED) { 49 | onRejected(this.reason) 50 | } 51 | // 当 then 是 pending 时,将这两个状态写入数组中 52 | if (this.state === STATE.PENDING) { 53 | this.fulfilledCallbacks.push(() => { 54 | onFulfilled(this.value) 55 | }) 56 | this.rejectedCallbacks.push(() => { 57 | onRejected(this.reason) 58 | }) 59 | } 60 | } 61 | } 62 | 63 | module.exports = MyPromise -------------------------------------------------------------------------------- /cloneDeep/test/clone4.test.js: -------------------------------------------------------------------------------- 1 | // 验证非递归深拷贝 2 | 3 | const cloneDeep = require('../src/clone4') 4 | 5 | const symbol = Symbol('sym') 6 | 7 | const data = { 8 | obj: {}, 9 | arr: [], 10 | reg: /reg/g, 11 | date: new Date('2019'), 12 | person: new Person('xxx'), 13 | [symbol]: 'symbol', 14 | set: new Set([{foo: 'set'}]), 15 | map: new Map([[{key: 'map'}, {value: 'map'}]]) 16 | } 17 | 18 | function Person(name) { 19 | this.name = name 20 | } 21 | 22 | const dataClone = cloneDeep(data) 23 | 24 | console.log('dataClone:\n', dataClone) 25 | 26 | // 验证引用关系 27 | console.log(data.obj === dataClone.obj) // false 28 | console.log(data.arr === dataClone.arr) // false 29 | console.log(data.reg === dataClone.reg) // false 30 | console.log(data.date === dataClone.date) // false 31 | console.log(data.func === dataClone.func) // true 32 | console.log([...data.set][0] === [...dataClone.set][0]) // false 33 | console.log([...data.map.keys()][0] === [...dataClone.map.keys()][0]) // false 34 | console.log([...data.map.values()][0] === [...dataClone.map.values()][0]) // false 35 | 36 | const temp = {} 37 | const data1 = { 38 | a: temp, 39 | b: temp, 40 | } 41 | const dataClone1 = cloneDeep(data1) 42 | 43 | const obj = {} 44 | obj.obj = obj 45 | 46 | const arr = [] 47 | arr[0] = arr 48 | 49 | const set = new Set() 50 | set.add(set) 51 | 52 | const map = new Map() 53 | map.set(map, map) 54 | 55 | // 验证引用关系 56 | console.log('dataClone1.a === dataClone1.b: ', dataClone1.a === dataClone1.b) // true 57 | 58 | // 验证循环引用 59 | console.log('obj:\n', cloneDeep(obj)) 60 | console.log('arr:\n', cloneDeep(arr)) 61 | console.log('set:\n', cloneDeep(set)) 62 | console.log('map:\n', cloneDeep(map)) -------------------------------------------------------------------------------- /cloneDeep/src/clone2.js: -------------------------------------------------------------------------------- 1 | // 处理其他数据类型 2 | 3 | const TYPE = { 4 | Object: 'Object', 5 | Array: 'Array', 6 | Date: 'Date', 7 | RegExp: 'RegExp', 8 | Set: 'Set', 9 | Map: 'Map', 10 | } 11 | 12 | // 获取数据类型 13 | const getType = (data) => Object.prototype.toString.call(data).slice(8, -1) 14 | 15 | // 深拷贝 16 | const cloneDeep = (data) => { 17 | if (!data || typeof data !== 'object') return data 18 | let cloneData = data 19 | const Constructor = data.constructor; 20 | const dataType = getType(data) 21 | // data 初始化 22 | if (dataType === TYPE.Array) { 23 | cloneData = [] 24 | } else if (dataType === TYPE.Object) { 25 | // 获取原对象的原型 26 | cloneData = Object.create(Object.getPrototypeOf(data)) 27 | } else if (dataType === TYPE.Date) { 28 | cloneData = new Constructor(data.getTime()) 29 | } else if (dataType === TYPE.RegExp) { 30 | const reFlags = /\w*$/ 31 | // 特殊处理regexp,拷贝过程中lastIndex属性会丢失 32 | cloneData = new Constructor(data.source, reFlags.exec(data)) 33 | cloneData.lastIndex = data.lastIndex 34 | } else if (dataType === TYPE.Set || dataType === TYPE.Map) { 35 | cloneData = new Constructor() 36 | } 37 | 38 | // 遍历 data 39 | if (dataType === TYPE.Set) { 40 | for (let value of data) { 41 | cloneData.add(cloneDeep(value)) 42 | } 43 | } else if (dataType === TYPE.Map) { 44 | for (let [mapKey, mapValue] of data) { 45 | // Map的键、值都可以是引用类型,因此都需要拷贝 46 | cloneData.set(cloneDeep(mapKey), cloneDeep(mapValue)) 47 | } 48 | } else { 49 | for (let key in data) { 50 | // 不考虑继承的属性 51 | if (data.hasOwnProperty(key)) { 52 | cloneData[key] = cloneDeep(data[key]) 53 | } 54 | } 55 | } 56 | return cloneData 57 | } 58 | 59 | module.exports = cloneDeep 60 | -------------------------------------------------------------------------------- /vueDataBind/Vue.js: -------------------------------------------------------------------------------- 1 | class Vue extends EventTarget{ 2 | constructor(options) { 3 | super(); 4 | this.options = options; 5 | this._data = this.options.data; 6 | this.el = document.getElementById(this.options.el); 7 | this.render(this.el); 8 | this.observe(this._data); 9 | } 10 | 11 | observe(data) { 12 | const _this = this 13 | this._data = new Proxy(data, { 14 | set: (target, name, value) => { 15 | // 定义自定义事件,传递数据更新后的值 16 | const event = new CustomEvent(name, { 17 | detail: value, 18 | }); 19 | // 发布事件 20 | _this.dispatchEvent(event); 21 | return Reflect.set(...arguments); 22 | } 23 | }) 24 | } 25 | 26 | render(el) { 27 | let childs = el.childNodes; 28 | [...childs].forEach(node => { 29 | // 文本节点 30 | if (node.nodeType === 3) { 31 | const text = node.textContent; 32 | const reg = /\{\{\s*([^\s\{\}]+)\s*\}\}/g; 33 | // 匹配 {{ name }} 34 | if (reg.test(text)) { 35 | const $1 = RegExp.$1; 36 | if (this._data[$1]) { 37 | node.textContent = text.replace(reg, this._data[$1]) 38 | // 监听自定义事件 39 | this.addEventListener($1, e => { 40 | node.textContent = text.replace(reg, e.detail) 41 | }) 42 | } 43 | } 44 | } else if(node.nodeType === 1) { 45 | // dom 节点 46 | const attrs = node.attributes; 47 | if (attrs.hasOwnProperty('v-model')) { 48 | const key = attrs['v-model'].nodeValue; 49 | node.value = this._data[key]; 50 | // 监听输入框输入,更新数据 51 | node.addEventListener('input', e => { 52 | this._data[key] = node.value 53 | }) 54 | } 55 | this.render(node); 56 | } 57 | }) 58 | } 59 | } -------------------------------------------------------------------------------- /cloneDeep/test/8.test.js: -------------------------------------------------------------------------------- 1 | // 比较不同深拷贝方法耗时 2 | const { JSDOM } = require('jsdom') 3 | const { window } = new JSDOM(``) 4 | const $ = require('jquery')(window) 5 | const _ = require('loadsh') 6 | const cloneDeep = require('../src/clone3') 7 | 8 | // 创建深度为depth,广度为breadth的数组 9 | function create(depth, breadth) { 10 | const data = {} 11 | let temp = data 12 | let i = j = 0 13 | while(i < depth) { 14 | temp = temp['data'] = {} 15 | while(j < breadth) { 16 | temp[j] = j 17 | j++ 18 | } 19 | i++ 20 | } 21 | return data 22 | } 23 | 24 | const data = create(1000, 1000) 25 | const counts = 10000 // 循环次数 26 | let i 27 | 28 | // JSON 29 | i = 0 30 | const jsonStart = new Date().getTime() 31 | while(i < counts) { 32 | JSON.parse(JSON.stringify(data)) 33 | i++ 34 | } 35 | const jsonEnd = new Date().getTime() 36 | console.log('Running JSON 10000 times cost:') 37 | console.log(`${jsonEnd - jsonStart} ms`) 38 | 39 | 40 | // $.extend 41 | i = 0 42 | const extendStart = new Date().getTime() 43 | while(i < counts) { 44 | $.extend(true, {}, data) 45 | i++ 46 | } 47 | const extendEnd = new Date().getTime() 48 | console.log('Running $.extend 10000 times cost:') 49 | console.log(`${extendEnd - extendStart} ms`) 50 | 51 | // cloneDeep 52 | i = 0 53 | const cloneStart = new Date().getTime() 54 | while(i < counts) { 55 | cloneDeep(data) 56 | i++ 57 | } 58 | const cloneEnd = new Date().getTime() 59 | console.log('Running cloneDeep 10000 times cost:') 60 | console.log(`${cloneEnd - cloneStart} ms`) 61 | 62 | 63 | // _.cloneDeep 64 | i = 0 65 | const _cloneStart = new Date().getTime() 66 | while(i < counts) { 67 | _.cloneDeep(data) 68 | i++ 69 | } 70 | const _cloneEnd = new Date().getTime() 71 | console.log('Running cloneDeep 10000 times cost:') 72 | console.log(`${_cloneEnd - _cloneStart} ms`) -------------------------------------------------------------------------------- /promise/src/promise3.js: -------------------------------------------------------------------------------- 1 | // 实现了链式调用、传递返回值 2 | 3 | const STATE = { 4 | PENDING: 'pending', 5 | FULFILLED: 'fulfilled', 6 | REJECTED: 'rejected' 7 | } 8 | 9 | class MyPromise { 10 | constructor(fn) { 11 | // 初始化 12 | this.state = STATE.PENDING 13 | this.value = null 14 | this.reason = null 15 | // 保存数组 16 | this.fulfilledCallbacks = [] 17 | this.rejectedCallbacks = [] 18 | // 成功 19 | const fulfill = (value) => { 20 | // 只有 state 为 pending 时,才可以更改状态 21 | if (this.state === STATE.PENDING) { 22 | this.state = STATE.FULFILLED 23 | this.value = value 24 | this.fulfilledCallbacks.forEach(cb => cb()) 25 | } 26 | } 27 | 28 | // 失败 29 | const reject = (reason) => { 30 | if (this.state === STATE.PENDING) { 31 | this.state = STATE.REJECTED 32 | this.reason = reason 33 | this.rejectedCallbacks.forEach(cb => cb()) 34 | } 35 | } 36 | // 执行函数出错时调用 reject 37 | try { 38 | fn(fulfill, reject) 39 | } catch (e) { 40 | reject(e) 41 | } 42 | } 43 | 44 | then(onFulfilled, onRejected) { 45 | return new MyPromise((fulfill, reject) => { 46 | if (this.state === STATE.FULFILLED) { 47 | // 将返回值传入下一个 fulfill 中 48 | fulfill(onFulfilled(this.value)) 49 | } 50 | if (this.state === STATE.REJECTED) { 51 | // 将返回值传入下一个 reject 中 52 | reject(onRejected(this.reason)) 53 | } 54 | // 当 then 是 pending 时,将这两个状态写入数组中 55 | if (this.state === STATE.PENDING) { 56 | this.fulfilledCallbacks.push(() => { 57 | fulfill(onFulfilled(this.value)) 58 | }) 59 | this.rejectedCallbacks.push(() => { 60 | reject(onRejected(this.reason)) 61 | }) 62 | } 63 | }) 64 | } 65 | } 66 | 67 | module.exports = MyPromise 68 | -------------------------------------------------------------------------------- /cloneDeep/src/clone3.js: -------------------------------------------------------------------------------- 1 | // 处理循环引用 2 | 3 | const TYPE = { 4 | Object: 'Object', 5 | Array: 'Array', 6 | Date: 'Date', 7 | RegExp: 'RegExp', 8 | Set: 'Set', 9 | Map: 'Map', 10 | } 11 | 12 | // 获取数据类型 13 | const getType = (data) => Object.prototype.toString.call(data).slice(8, -1) 14 | 15 | // 深拷贝 16 | const cloneDeep = (data, hash = new WeakMap()) => { 17 | if (!data || typeof data !== 'object') return data 18 | // 查询是否已拷贝 19 | if(hash.has(data)) return hash.get(data) 20 | let cloneData = data 21 | const Constructor = data.constructor; 22 | const dataType = getType(data) 23 | // data 初始化 24 | if (dataType === TYPE.Array) { 25 | cloneData = [] 26 | } else if (dataType === TYPE.Object) { 27 | // 获取原对象的原型 28 | cloneData = Object.create(Object.getPrototypeOf(data)) 29 | } else if (dataType === TYPE.Date) { 30 | cloneData = new Constructor(data.getTime()) 31 | } else if (dataType === TYPE.RegExp) { 32 | const reFlags = /\w*$/ 33 | // 特殊处理regexp,拷贝过程中lastIndex属性会丢失 34 | cloneData = new Constructor(data.source, reFlags.exec(data)) 35 | cloneData.lastIndex = data.lastIndex 36 | } else if (dataType === TYPE.Set || dataType === TYPE.Map) { 37 | cloneData = new Constructor() 38 | } 39 | // 写入 hash 40 | hash.set(data, cloneData) 41 | // 遍历 data 42 | if (dataType === TYPE.Set) { 43 | for (let value of data) { 44 | cloneData.add(cloneDeep(value, hash)) 45 | } 46 | } else if (dataType === TYPE.Map) { 47 | for (let [mapKey, mapValue] of data) { 48 | // Map的键、值都可以是引用类型,因此都需要拷贝 49 | cloneData.set(cloneDeep(mapKey, hash), cloneDeep(mapValue, hash)) 50 | } 51 | } else { 52 | for (let key in data) { 53 | // 不考虑继承的属性 54 | if (data.hasOwnProperty(key)) { 55 | cloneData[key] = cloneDeep(data[key], hash) 56 | } 57 | } 58 | } 59 | return cloneData 60 | } 61 | 62 | module.exports = cloneDeep 63 | -------------------------------------------------------------------------------- /promise/test/promise5.test.js: -------------------------------------------------------------------------------- 1 | const MyPromise = require('../src/promise5') 2 | 3 | const promise = new MyPromise((resolve) => { 4 | setTimeout(() => { 5 | resolve(1) 6 | }, 100) 7 | }) 8 | 9 | // catch、finally test 10 | promise.then((value) => { 11 | console.log('value1', value); 12 | return new MyPromise((resolve, reject) => { 13 | setTimeout(() => { 14 | reject(2) 15 | }, 100) 16 | }) 17 | }) 18 | .then((value) => { 19 | console.log('value2', value); 20 | }) 21 | .catch(e => { 22 | console.log('err', e); 23 | }) 24 | .finally(() => { 25 | console.log('fin'); 26 | }) 27 | 28 | // resolve test 29 | const thenable = { 30 | then: function(resolve, reject) { 31 | resolve(42); 32 | } 33 | }; 34 | 35 | MyPromise.resolve(thenable) 36 | .then(val => { 37 | console.log('resolve1', val); 38 | }) 39 | 40 | console.log('resolve2', MyPromise.resolve(1)) 41 | 42 | // race test 43 | MyPromise.race([new MyPromise((resolve) => { 44 | setTimeout(() => { 45 | resolve(1) 46 | }, 1000) 47 | }), new MyPromise((resolve) => { 48 | setTimeout(() => { 49 | resolve(2) 50 | }, 500) 51 | }), 3]) 52 | .then(val => { 53 | console.log('race', val); 54 | }) 55 | 56 | // all test 57 | MyPromise.all([new MyPromise((resolve) => { 58 | setTimeout(() => { 59 | resolve(1) 60 | }, 1000) 61 | }), new MyPromise((resolve) => { 62 | setTimeout(() => { 63 | resolve(2) 64 | }, 500) 65 | })]) 66 | .then(val => { 67 | console.log('all1', val); 68 | }) 69 | 70 | MyPromise.all([new MyPromise((resolve) => { 71 | setTimeout(() => { 72 | resolve(1) 73 | }, 1000) 74 | }), new MyPromise((resolve, reject) => { 75 | setTimeout(() => { 76 | reject(2) 77 | }, 500) 78 | })]) 79 | .catch(e => { 80 | console.log('all2', e); 81 | }) 82 | 83 | MyPromise.allSettled([new MyPromise((resolve) => { 84 | setTimeout(() => { 85 | resolve(1) 86 | }, 1000) 87 | }), new MyPromise((resolve, reject) => { 88 | setTimeout(() => { 89 | reject(2) 90 | }, 500) 91 | })]) 92 | .then(arr => { 93 | console.log('allSettled', arr); 94 | }) 95 | -------------------------------------------------------------------------------- /typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | /* 构建、工程化选项 */ 4 | 5 | // baseUrl: 解析的根目录 6 | "baseUrl": "src", 7 | // target: 编译代码到目标 ECMAScript 版本,一般是 es5/es6 8 | "target": "es5", 9 | // lib: 运行时环境支持的语法,默认与 tagert 的值相关联 10 | "lib": ["dom", "es5", "es6", "esnext"], 11 | // module: 编译产物对应的模块化标准,常用值包括 commonjs/es6/esnext 等 12 | "module": "esnext", 13 | // moduleResolution: 模块解析策略,支持 node/classic,后者基本不推荐使用 14 | "moduleResolution": "node", 15 | // allowJs:是否允许引入 .js 文件 16 | "allowJs": true, 17 | // checkJs: 是否检查 .js 文件中的错误 18 | "checkJs": true, 19 | // declaration: 是否生成对应的 .d.ts 类型文件,一般作为 npm 包提供时需要开启 20 | "declaration": false, 21 | // sourceMap: 是否生成对应的 .map 文件 22 | "sourceMap": true, 23 | // noEmit: 是否将构建产物写入文件系统,一个常见的实践是只用 tsc 进行类型检查,使用单独的打包工具进行打包 24 | "noEmit": true, 25 | // jsx: 如何处理 .tsx 文件中对于 jsx 的生成,常用值包括:react/preserve 26 | // 详细比对:https://www.typescriptlang.org/tsconfig#jsx 27 | "jsx": "preserve", 28 | // esModuleInterop: 开启后会生成辅助函数以兼容处理在 esm 中导入 cjs 的情况 29 | "esModuleInterop": true, 30 | // allowSyntheticDefaultImports: 在 cjs 没有默认导出时进行兼容,配合 esModuleInterop 使用 31 | "allowSyntheticDefaultImports": true, 32 | // forceConsistentCasingInFileNames: 是否强制导入文件时与系统文件的大小写一致 33 | "forceConsistentCasingInFileNames": true, 34 | // resolveJsonModule:是否支持导入 json 文件,并做类型推导和检查 35 | "resolveJsonModule": true, 36 | // experimentalDecorators: 是否支持装饰器实验性语法 37 | "experimentalDecorators": true, 38 | 39 | /* 类型检查选项 */ 40 | 41 | // strict: 是否启动严格的类型检查,包含一系列选项:https://www.typescriptlang.org/tsconfig#strict 42 | "strict": true, 43 | // skipLibCheck: 是否跳过非源代码中所有类型声明文件(.d.ts)的检查 44 | "skipLibCheck": true, 45 | // strictNullChecks: 是否启用严格的 null 检查 46 | "strictNullChecks": true, 47 | // noImplicitAny: 包含隐式 any 声明时是否报错 48 | "noImplicitAny": true, 49 | // noImplicitReturns: 是否要求所有函数执行路径中都有返回值 50 | "noImplicitReturns": true, 51 | // noUnusedLocals: 存在未使用的变量时是否报错 52 | "noUnusedLocals": false, 53 | // noUnusedParameters: 存在未使用的参数时是否报错 54 | "noUnusedParameters": false, 55 | } 56 | } -------------------------------------------------------------------------------- /cloneDeep/src/clone4.js: -------------------------------------------------------------------------------- 1 | // 使用非递归实现cloneDeep 2 | 3 | const TYPE = { 4 | Object: 'Object', 5 | Array: 'Array', 6 | Date: 'Date', 7 | RegExp: 'RegExp', 8 | Set: 'Set', 9 | Map: 'Map', 10 | } 11 | 12 | // 获取数据类型 13 | const getType = (data) => Object.prototype.toString.call(data).slice(8, -1) 14 | 15 | // 初始化item并入栈 16 | function generate(item, stack, hash) { 17 | if (!item || typeof item !== 'object') return item 18 | if(hash.has(item)) return hash.get(item) 19 | let cloneItem = item 20 | const Constructor = item.constructor 21 | const itemType = getType(item) 22 | // data 初始化 23 | if (itemType === TYPE.Array) { 24 | cloneItem = [] 25 | } else if (itemType === TYPE.Object) { 26 | // 获取原对象的原型 27 | cloneItem = Object.create(Object.getPrototypeOf(item)) 28 | } else if (itemType === TYPE.Date) { 29 | cloneItem = new Constructor(item.getTime()) 30 | } else if (itemType === TYPE.RegExp) { 31 | const reFlags = /\w*$/ 32 | // 特殊处理regexp,拷贝过程中lastIndex属性会丢失 33 | cloneItem = new Constructor(item.source, reFlags.exec(item)) 34 | cloneItem.lastIndex = item.lastIndex 35 | } else if (itemType === TYPE.Set || itemType === TYPE.Map) { 36 | cloneItem = new Constructor() 37 | } 38 | stack.push({ 39 | target: cloneItem, 40 | source: item, 41 | }) 42 | hash.set(item, cloneItem) 43 | return cloneItem 44 | } 45 | 46 | function cloneDeep(data) { 47 | // 初始化hash 48 | const hash = new WeakMap() 49 | // 初始化stack 50 | const stack = [] 51 | const cloneData = generate(data, stack, hash) 52 | while(stack.length > 0) { 53 | // 栈顶节点出栈 54 | const node = stack.pop() 55 | const { target, source } = node 56 | const type = getType(source) 57 | // 遍历 source 58 | if (type === TYPE.Set) { 59 | for (let value of source) { 60 | target.add(generate(value, stack, hash)) 61 | } 62 | } else if (type === TYPE.Map) { 63 | for (let [mapKey, mapValue] of source) { 64 | target.set(generate(mapKey, stack, hash), generate(mapValue, stack, hash)) 65 | } 66 | } else { 67 | for (let key in source) { 68 | // 不考虑继承的属性 69 | if (source.hasOwnProperty(key)) { 70 | target[key] = generate(source[key], stack, hash) 71 | } 72 | } 73 | } 74 | } 75 | return cloneData 76 | } 77 | 78 | module.exports = cloneDeep 79 | -------------------------------------------------------------------------------- /pnpm/01-npm@2/node_modules/demo-baz/node_modules/demo-bar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-bar", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "author": "", 9 | "license": "ISC", 10 | "_id": "demo-bar@1.0.0", 11 | "_nodeVersion": "14.20.1", 12 | "_npmVersion": "6.14.17", 13 | "dist": { 14 | "integrity": "sha512-M32T7z7T8L6+YNWtLhWi2Cul7K6U5yAziWME2fhPHX36XWFUdVyCy6PJD3XdFBKy0cacfWSfEJTWmBkB5f4iEw==", 15 | "shasum": "842e7e2c482ade053a886a38b8bebd9d47356c7b", 16 | "tarball": "https://registry.npmjs.org/demo-bar/-/demo-bar-1.0.0.tgz", 17 | "fileCount": 2, 18 | "unpackedSize": 224, 19 | "signatures": [ 20 | { 21 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", 22 | "sig": "MEYCIQDQgiDnizuY+1qhVZMnGJEFBrbet1T7qhmFOBiePsLn/AIhAK+EyJD49lvxdsC37qE2vfM4ODxhx70ILuMbAkSMagML" 23 | } 24 | ], 25 | "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjVT+dACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrGqQ/9FK+dxAeizFGD49fOjRnV+leoW68Mdk5FBKmFztrDqGTFmKpJ\r\npJZ858TKrZpf2gjZLcYkCwdUvJZV8xAkdd8zFwasIkd4rd5CZ4ToNzOvwrVT\r\nvWNimGfSyHkGYgBNB1kDwtjDDKQ8+9USUWTjhPEMuadCMW8V5uzAPevA17+g\r\nNSKz+Db1oMlSRzd4UYiYirUgO2qAU6Gg4LXE4pYl8GStPBj8p7nF1XlnWcrd\r\n3AkvH40ed9W7P1b2Pf7hclUV/1Hdx2Jlpys9PcheL5Bf8kCIA7wnb7IaHK1F\r\nRqGLeoRNg5IgE4AOqXcQ8iw4Y7+f8W1QYFBO9VzSEpj755NS0u2fyiUs66EO\r\n/+AzO0kP5s9ARnbP7NRFXg8PHIeQAvrqT65QNPbzHgMTT6GrO6Imz7SGREeP\r\n4XwWcC6iZ8HT002Uf32mA6DeYK3i+9uzRpbsyNcvNClgEh2P+KD52XtQp9bY\r\naEi+I6PJutZ5npLS7Yn0bFArh8rkzvgQ6fZY47MT0PxPs9LiEkZFrUdvVtfp\r\n1mzUa87oEsQPoHl/VBiYV2E9YfkMiM8xZhP0wzD2PdNibo0b1JIohWr3bZ2n\r\n/jSBGGg0yqSWn/Sy3l3bncssjQreKqQ9W125cJyaH3CRW2eNwTPZHqmF3Cju\r\n0sOPuznK0qp/u8FRH+tlpKAQO15xHsz0bCw=\r\n=EERK\r\n-----END PGP SIGNATURE-----\r\n" 26 | }, 27 | "_npmUser": { 28 | "name": "lvqq", 29 | "email": "nicksonlvqq@gmail.com" 30 | }, 31 | "directories": {}, 32 | "maintainers": [ 33 | { 34 | "name": "lvqq", 35 | "email": "nicksonlvqq@gmail.com" 36 | } 37 | ], 38 | "_npmOperationalInternal": { 39 | "host": "s3://npm-registry-packages", 40 | "tmp": "tmp/demo-bar_1.0.0_1666531228971_0.3777985296894073" 41 | }, 42 | "_hasShrinkwrap": false, 43 | "_shasum": "842e7e2c482ade053a886a38b8bebd9d47356c7b", 44 | "_resolved": "https://registry.npmjs.org/demo-bar/-/demo-bar-1.0.0.tgz", 45 | "_from": "demo-bar@1.0.0", 46 | "readme": "ERROR: No README data found!" 47 | } 48 | -------------------------------------------------------------------------------- /pnpm/01-npm@2/node_modules/demo-foo/node_modules/demo-bar/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-bar", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1" 7 | }, 8 | "author": "", 9 | "license": "ISC", 10 | "_id": "demo-bar@1.0.0", 11 | "_nodeVersion": "14.20.1", 12 | "_npmVersion": "6.14.17", 13 | "dist": { 14 | "integrity": "sha512-M32T7z7T8L6+YNWtLhWi2Cul7K6U5yAziWME2fhPHX36XWFUdVyCy6PJD3XdFBKy0cacfWSfEJTWmBkB5f4iEw==", 15 | "shasum": "842e7e2c482ade053a886a38b8bebd9d47356c7b", 16 | "tarball": "https://registry.npmjs.org/demo-bar/-/demo-bar-1.0.0.tgz", 17 | "fileCount": 2, 18 | "unpackedSize": 224, 19 | "signatures": [ 20 | { 21 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", 22 | "sig": "MEYCIQDQgiDnizuY+1qhVZMnGJEFBrbet1T7qhmFOBiePsLn/AIhAK+EyJD49lvxdsC37qE2vfM4ODxhx70ILuMbAkSMagML" 23 | } 24 | ], 25 | "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjVT+dACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrGqQ/9FK+dxAeizFGD49fOjRnV+leoW68Mdk5FBKmFztrDqGTFmKpJ\r\npJZ858TKrZpf2gjZLcYkCwdUvJZV8xAkdd8zFwasIkd4rd5CZ4ToNzOvwrVT\r\nvWNimGfSyHkGYgBNB1kDwtjDDKQ8+9USUWTjhPEMuadCMW8V5uzAPevA17+g\r\nNSKz+Db1oMlSRzd4UYiYirUgO2qAU6Gg4LXE4pYl8GStPBj8p7nF1XlnWcrd\r\n3AkvH40ed9W7P1b2Pf7hclUV/1Hdx2Jlpys9PcheL5Bf8kCIA7wnb7IaHK1F\r\nRqGLeoRNg5IgE4AOqXcQ8iw4Y7+f8W1QYFBO9VzSEpj755NS0u2fyiUs66EO\r\n/+AzO0kP5s9ARnbP7NRFXg8PHIeQAvrqT65QNPbzHgMTT6GrO6Imz7SGREeP\r\n4XwWcC6iZ8HT002Uf32mA6DeYK3i+9uzRpbsyNcvNClgEh2P+KD52XtQp9bY\r\naEi+I6PJutZ5npLS7Yn0bFArh8rkzvgQ6fZY47MT0PxPs9LiEkZFrUdvVtfp\r\n1mzUa87oEsQPoHl/VBiYV2E9YfkMiM8xZhP0wzD2PdNibo0b1JIohWr3bZ2n\r\n/jSBGGg0yqSWn/Sy3l3bncssjQreKqQ9W125cJyaH3CRW2eNwTPZHqmF3Cju\r\n0sOPuznK0qp/u8FRH+tlpKAQO15xHsz0bCw=\r\n=EERK\r\n-----END PGP SIGNATURE-----\r\n" 26 | }, 27 | "_npmUser": { 28 | "name": "lvqq", 29 | "email": "nicksonlvqq@gmail.com" 30 | }, 31 | "directories": {}, 32 | "maintainers": [ 33 | { 34 | "name": "lvqq", 35 | "email": "nicksonlvqq@gmail.com" 36 | } 37 | ], 38 | "_npmOperationalInternal": { 39 | "host": "s3://npm-registry-packages", 40 | "tmp": "tmp/demo-bar_1.0.0_1666531228971_0.3777985296894073" 41 | }, 42 | "_hasShrinkwrap": false, 43 | "_shasum": "842e7e2c482ade053a886a38b8bebd9d47356c7b", 44 | "_resolved": "https://registry.npmjs.org/demo-bar/-/demo-bar-1.0.0.tgz", 45 | "_from": "demo-bar@1.0.0", 46 | "readme": "ERROR: No README data found!" 47 | } 48 | -------------------------------------------------------------------------------- /pnpm/01-npm@2/node_modules/demo-baz/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-baz", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-bar": "1.0.0" 13 | }, 14 | "_id": "demo-baz@1.0.0", 15 | "_nodeVersion": "14.20.1", 16 | "_npmVersion": "6.14.17", 17 | "dist": { 18 | "integrity": "sha512-Q5WJf+3qk2kZ+wV8Y+EiJNqN9uATjfSR29Ml7HUMLFSoGP/OeG8MYe3lvlEmidmE5GKBAszzCW5wUVJU3t5RQg==", 19 | "shasum": "0ce32889e87a71064481fa3504274fee5b46983c", 20 | "tarball": "https://registry.npmjs.org/demo-baz/-/demo-baz-1.0.0.tgz", 21 | "fileCount": 2, 22 | "unpackedSize": 292, 23 | "signatures": [ 24 | { 25 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", 26 | "sig": "MEQCIARPX99sII5IcNOifCUuicyu5/qqZtNHurt6uazFSw8vAiBm7zuiw0QKbnJfRbQaX5+NDXSE1sy0U3afObWg0GvAJw==" 27 | } 28 | ], 29 | "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjVUWGACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmp/hg//TS0dGWr1XbKYhx6nKZOot76kBaluLTTHC6DiabsZnrXaRKko\r\nIklHVGL7EBndqbasRQVK/8rOkYv88NyZBkbbLK8J5oT7HTpktUCcg1TzEORz\r\nGyvuEJYWKG9U2khn5dfJFF7z8hqTS/v23zuqJRHHXrKXb2TjIC3YwcE9RUPx\r\nafGEdqNZIfCHL1lXckBjXDoyrCLNa5qa6x1PZE6Ot2EkQjgqFPNIZ7k0wPCH\r\nTdPQhOTsMAWpyysg3Y4MabjXMYGRb6oG2FnnElOUWsMVSs4HtiSUcPntnfuz\r\naFXOwCIxIhmsD2/gdgoHGBn7i29AUqzNuMADe7+wbebYW/adAgHWlI9qspNk\r\nUv0Uo2/mq8poZYJsTfZ3LugNsZ/hc0AsKP92QMT99ALKqk5n1EL+rO4zBtRq\r\nY1tf59dpqckeXJ8+7UUKibew94GhGSYyewhvkX8pV12emeZOUyJUfNQjM3Kp\r\nUG2izMynfsFW/CECc+fwQos1wT8MsWZMhJ2qAT/5hyN2oVpcojg04LIBVcYm\r\nOy0fDm9lFWoIQoPIBabcoXKR+bvstZisgt12OJuhZ/7QyboJC4Q34JwxeDjj\r\nnL+ve3P8q49Ed4Ia0rY1uBlwTAMr1UIFYwNtVjEgB7w5Q8Fgb+AGyZnow/UC\r\nqg+YgBla6+tvW1n28MTwR3ffUeT6Etpa+I0=\r\n=69V5\r\n-----END PGP SIGNATURE-----\r\n" 30 | }, 31 | "_npmUser": { 32 | "name": "lvqq", 33 | "email": "nicksonlvqq@gmail.com" 34 | }, 35 | "directories": {}, 36 | "maintainers": [ 37 | { 38 | "name": "lvqq", 39 | "email": "nicksonlvqq@gmail.com" 40 | } 41 | ], 42 | "_npmOperationalInternal": { 43 | "host": "s3://npm-registry-packages", 44 | "tmp": "tmp/demo-baz_1.0.0_1666532742593_0.743925781059384" 45 | }, 46 | "_hasShrinkwrap": false, 47 | "_shasum": "0ce32889e87a71064481fa3504274fee5b46983c", 48 | "_resolved": "https://registry.npmjs.org/demo-baz/-/demo-baz-1.0.0.tgz", 49 | "_from": "demo-baz@1.0.0", 50 | "readme": "ERROR: No README data found!" 51 | } 52 | -------------------------------------------------------------------------------- /pnpm/01-npm@2/node_modules/demo-foo/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "demo-foo", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "demo-bar": "1.0.0" 13 | }, 14 | "_id": "demo-foo@1.0.0", 15 | "_nodeVersion": "14.20.1", 16 | "_npmVersion": "6.14.17", 17 | "dist": { 18 | "integrity": "sha512-VeRVrfGWqCvZLL9BTq7ZDNroR9ve7Yh3n7DI/RI1CcdQpCzTbxmAaT3YdKv4/lAQGGLws9Wwrx+PQCszCX+n6g==", 19 | "shasum": "53a114df5a7cdd0137fb68b01f0a6f0882d0c6b3", 20 | "tarball": "https://registry.npmjs.org/demo-foo/-/demo-foo-1.0.0.tgz", 21 | "fileCount": 2, 22 | "unpackedSize": 295, 23 | "signatures": [ 24 | { 25 | "keyid": "SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA", 26 | "sig": "MEUCIHJmeXOtnC5spuTeeLlsokRoyXzONuw46MAYbZOOI72ZAiEA1/oaP4ca+ouVwmYotxcDbuDNSmdEAZUQbEahxjMeM94=" 27 | } 28 | ], 29 | "npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjVT/FACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo32g/9FO6s72IhxXX+OM0blQnVBBV8lfAvVS8M7mKBXnenzRsmkLnR\r\noVfC7a/X+s0vR3RWEoVufXeWfZywrRBngU/3q4WePAtKOgQG9PQepmj/pUxX\r\nP0RbNqCnCsMhWNeu8WKRMIvdfPaSqZgB3nCw8j/k+/qAit0qNpWWmCkUWpQs\r\nCfzR4bAjMNhihALEmjaztuYPElQFbyeZq/DshNAqbyL/L+yUZu5jg1xv1cQd\r\n++cLCA3rn7sjPT5gYQW79EAgPSlwbvoA/5PN6A5bdlE99ZQmf+Wv2Kv6LPSl\r\nOyMLko/uigvn79tKXxEdMryRBtX1sOx00eKY3xgE3gpMlLz+cu9gQkTFjl4A\r\n3Cm3RpJdHsvote0SZdBVerURA6f8VWV+1Ecfj9wpXa/ukJpDZxLOwQawmtYc\r\n78KbEHqyRqmshIUZvo1rT5X5ReCYCXHmctoezew3kx/ejwzWMhESsNzvkpjt\r\niF1Bz8HgIqjfKQ2L6Pn7JmUCBUvlTMnF977UzucG1ZBNAROpYQb3EzKLdIej\r\n2DH8lk09p2IlHMOsCY25Ty8juU5ZitfAJOaIpI9zrno9qY7KWIuM9EfpXGUs\r\nsjVUhuuEOnohSuogLy/7l9vzYFg9NmfvRd6INyHDr5jor9AsMAURQ7NgPh3+\r\n6A7QtjHqAf4cV66nKLQzovqX7JMXZ8dffKk=\r\n=kpbO\r\n-----END PGP SIGNATURE-----\r\n" 30 | }, 31 | "_npmUser": { 32 | "name": "lvqq", 33 | "email": "nicksonlvqq@gmail.com" 34 | }, 35 | "directories": {}, 36 | "maintainers": [ 37 | { 38 | "name": "lvqq", 39 | "email": "nicksonlvqq@gmail.com" 40 | } 41 | ], 42 | "_npmOperationalInternal": { 43 | "host": "s3://npm-registry-packages", 44 | "tmp": "tmp/demo-foo_1.0.0_1666531269124_0.18467285083543294" 45 | }, 46 | "_hasShrinkwrap": false, 47 | "_shasum": "53a114df5a7cdd0137fb68b01f0a6f0882d0c6b3", 48 | "_resolved": "https://registry.npmjs.org/demo-foo/-/demo-foo-1.0.0.tgz", 49 | "_from": "demo-foo@1.0.0", 50 | "readme": "ERROR: No README data found!" 51 | } 52 | -------------------------------------------------------------------------------- /amplifier/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 放大器 6 | 7 | 37 | 38 |
39 | 40 |
41 |
42 |
43 | 44 |
45 | 46 | 93 | -------------------------------------------------------------------------------- /browserCache/static/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 13 | 14 | 15 |
16 | 30 |
31 | 35 | 99 | 100 | -------------------------------------------------------------------------------- /gulp-demo/gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | less = require('gulp-less'), //less 转 css 3 | csso = require('gulp-csso'), //css压缩 4 | concat = require('gulp-concat'), //合并文件 5 | uglify = require('gulp-uglify'), //js 压缩 6 | jshint = require('gulp-jshint'), //js 检查 7 | clean = require('gulp-clean'), //清除文件 8 | imagemin = require('gulp-imagemin'), //图片压缩 9 | rev = require('gulp-rev'), //添加版本号 10 | revReplace = require('gulp-rev-replace'), //版本号替换 11 | useref = require('gulp-useref'), //解析html资源定位 12 | gulpif = require('gulp-if'), //if语句 13 | connect = require('gulp-connect'); //创建web服务器 14 | 15 | //图片压缩 16 | gulp.task('dist:img', () => { 17 | gulp.src(['./src/**/*.jpg', './src/**/*.png']) 18 | .pipe(imagemin()) 19 | .pipe(gulp.dest('dist/')) 20 | }) 21 | 22 | //less转css压缩合并 23 | gulp.task('dist:css', () => { 24 | gulp.src('dist/css/*.css').pipe(clean()); 25 | return gulp.src('./src/less/*.less') 26 | .pipe(less()) 27 | .pipe(csso()) 28 | .pipe(concat('public.css')) 29 | .pipe(gulp.dest('dist/css/')); 30 | }); 31 | 32 | //less转css 33 | gulp.task('src:css', () => { 34 | gulp.src('src/css/*.css').pipe(clean()); 35 | return gulp.src('./src/less/*.less') 36 | .pipe(less()) 37 | .pipe(gulp.dest('src/css/')); 38 | }); 39 | 40 | //js压缩合并 41 | gulp.task('dist:js', () => { 42 | gulp.src('dist/js/*.js').pipe(clean()); 43 | return gulp.src('./src/js/*.js') 44 | .pipe(jshint()) 45 | .pipe(jshint.reporter('default')) 46 | .pipe(uglify()) 47 | .pipe(concat('public.js')) 48 | .pipe(gulp.dest('dist/js/')) 49 | }); 50 | 51 | //添加版本号 52 | gulp.task('revision', ['dist:css', 'dist:js'], () => { 53 | return gulp.src(["dist/css/*.css", "dist/js/*.js"]) 54 | .pipe(rev()) 55 | .pipe(gulpif('*.css', gulp.dest('dist/css'), gulp.dest('dist/js'))) 56 | .pipe(rev.manifest()) 57 | .pipe(gulp.dest('dist')) 58 | }) 59 | 60 | //替换html 61 | gulp.task('build', ['dist:img'], () => { 62 | var manifest = gulp.src('dist/rev-manifest.json'); 63 | return gulp.src('src/index.html') 64 | .pipe(revReplace({ 65 | manifest: manifest 66 | })) 67 | .pipe(useref()) 68 | .pipe(gulp.dest('dist/')) 69 | }) 70 | 71 | //创建本地服务器 72 | gulp.task('connect', () => { 73 | connect.server({ 74 | root: 'src', 75 | livereload: true, 76 | port: 8888 77 | }) 78 | }) 79 | 80 | //设置自动刷新 81 | gulp.task('reload', () => { 82 | gulp.src('src/*.html') 83 | .pipe(connect.reload()) 84 | }) 85 | 86 | //监听src变化 87 | gulp.task('watch', () => { 88 | gulp.watch('src/**/*', ['src:css', 'reload']) 89 | }) 90 | 91 | //清除 92 | gulp.task('clean', () => { 93 | gulp.src('dist/*', {read: false}) 94 | .pipe(clean()) 95 | }) 96 | 97 | gulp.task('default', ['connect','watch']); -------------------------------------------------------------------------------- /typescript/03-sample.ts: -------------------------------------------------------------------------------- 1 | /* =============== 泛型 =============== */ 2 | 3 | 4 | // 定义 5 | type Test3 = T | string; 6 | // 使用 7 | const test: Test3 = 1 8 | // react 中的例子 9 | // const [state, setState] = useState(0) 10 | 11 | 12 | 13 | // 函数式声明 14 | function func3(param: T): T { 15 | return param; 16 | } 17 | 18 | // 表达式声明 19 | const func4: (param: T) => T = (param) => { 20 | return param; 21 | } 22 | 23 | 24 | /* =============== typeof =============== */ 25 | 26 | const str4 = 'text' 27 | type Str = typeof str // string 28 | 29 | 30 | 31 | 32 | const obj = { 33 | field1: 'text', 34 | field2: 1, 35 | field3: { 36 | field: 'text' 37 | } 38 | } 39 | 40 | type ObjType = typeof obj 41 | // { 42 | // field1: string; 43 | // field2: number; 44 | // field3: { 45 | // field: string; 46 | // }; 47 | // } 48 | 49 | 50 | /* =============== keyof =============== */ 51 | interface Test4 { 52 | field1: string; 53 | field2: number; 54 | } 55 | 56 | type Fields1 = keyof Test4 57 | // "field1" | "field2" 58 | 59 | 60 | /* =============== in =============== */ 61 | 62 | type Fields2 = 'field1' | 'field2' 63 | type Test5 = { 64 | [key in Fields2]: string 65 | } 66 | // Test: { field1: string; field2: string } 67 | 68 | 69 | 70 | /* =============== extends =============== */ 71 | 72 | 73 | type Test6 = T[] 74 | type TestExtends1 = Test6 // success 75 | type TestExtends2 = Test6 // Type 'boolean' does not satisfy the constraint 'string | number'. 76 | 77 | 78 | 79 | type Test7 = T extends string | number ? T[] : T 80 | type TestExtends3 = Test7 // string[] 81 | type TestExtends4 = Test7 // boolean 82 | 83 | 84 | 85 | /* =============== infer =============== */ 86 | type MyReturnType any> = T extends ( 87 | ...args: any 88 | ) => infer R ? R : any 89 | 90 | 91 | /* =============== 索引类型 =============== */ 92 | 93 | interface Test8 { 94 | [key: string]: string; 95 | } 96 | 97 | 98 | 99 | interface Test9 { 100 | // Error: Property 'field' of type 'number' is not assignable to 'string' index type 'string' 101 | field: number; 102 | [key: string]: string; 103 | } 104 | 105 | 106 | 107 | interface Test10 { 108 | field1: string; 109 | field2: number; 110 | } 111 | 112 | type Fields3 = keyof Test10 113 | // "field1" | "field2" 114 | 115 | 116 | 117 | interface Test11 { 118 | field1: string; 119 | field2: number 120 | } 121 | 122 | type Field1 = Test11["field1"] // string 123 | type Field2 = Test11["field2"] // number 124 | // 配合 keyof,可以获取索引签名对应类型的联合类型 125 | type Fields4 = Test11[keyof Test11] // string | number 126 | 127 | 128 | 129 | interface Test12 { 130 | [key: string]: number; 131 | } 132 | 133 | type Field3 = Test12[string] // number 134 | 135 | 136 | 137 | /* =============== 映射类型 =============== */ 138 | 139 | type ToString = { 140 | [key in keyof T]: string 141 | } 142 | 143 | interface Test13 { 144 | field1: string; 145 | field2: number; 146 | field3: boolean; 147 | } 148 | 149 | type Fields5 = ToString 150 | -------------------------------------------------------------------------------- /typescript/04-sample.ts: -------------------------------------------------------------------------------- 1 | /* =============== Partial =============== */ 2 | 3 | type MyPartial = { 4 | [P in keyof T]?: T[P] | undefined; 5 | } 6 | 7 | 8 | 9 | interface Person7 { 10 | name: string; 11 | age?: number; 12 | } 13 | type PersonPartial = Partial 14 | // { name?: string | undefined; age?: number | undefined } 15 | 16 | 17 | 18 | type DeepPartial = { 19 | [P in keyof T]?: T[P] extends object ? DeepPartial : T[P] | undefined 20 | } 21 | 22 | /* =============== Required =============== */ 23 | 24 | type MyRequired = { 25 | [P in keyof T]-?: T[P]; 26 | } 27 | 28 | 29 | 30 | interface Person8 { 31 | name: string; 32 | age?: number; 33 | } 34 | 35 | type PersonRequired = Required 36 | // { name: string; age: number } 37 | 38 | /* =============== Readonly =============== */ 39 | type MyReadonly = { 40 | readonly [P in keyof T]: T[P]; 41 | } 42 | 43 | 44 | 45 | interface Person9 { 46 | name: string; 47 | age?: number; 48 | } 49 | 50 | type PersonReadonly = Readonly 51 | // { readonly name: string; readonly age?: number | undefined } 52 | 53 | 54 | /* =============== Record =============== */ 55 | type MyRecord = { 56 | [P in K]: T; 57 | } 58 | 59 | /* =============== Exclude =============== */ 60 | type MyExclude = T extends U ? never : T 61 | 62 | 63 | 64 | type Test14 = string | number 65 | type TestExclude = Exclude // number 66 | 67 | /* =============== Extract =============== */ 68 | type MyExtract = T extends U ? T : never 69 | 70 | 71 | type Test15 = string | number 72 | type TestExtract = Extract // string 73 | 74 | /* =============== NonNullable =============== */ 75 | type MyNonNullable = T extends null | undefined ? never : T 76 | 77 | 78 | type Test16 = string | number | null | undefined 79 | type TestNonNullable = NonNullable // string | number 80 | 81 | /* =============== Pick =============== */ 82 | type MyPick = { 83 | [P in K]: T[P]; 84 | } 85 | 86 | 87 | 88 | interface Person10 { 89 | name: string; 90 | age?: number; 91 | } 92 | 93 | type PersonPick = Pick 94 | // { age?: number } 95 | 96 | /* =============== Omit =============== */ 97 | type MyOmit = { 98 | [P in Exclude]: T[P]; 99 | } 100 | 101 | 102 | interface Person11 { 103 | name: string; 104 | age?: number; 105 | } 106 | 107 | type PersonOmit = Omit 108 | // { age?: number } 109 | 110 | /* =============== Parameters =============== */ 111 | 112 | type MyParameters any> = T extends ( 113 | ...args: infer P 114 | ) => any ? P : never 115 | 116 | 117 | 118 | type Func1 = (param: string) => string[] 119 | type FuncParam = Parameters // [param: string] 120 | 121 | /* =============== ReturnType =============== */ 122 | 123 | type MyReturnType2 any> = T extends ( 124 | ...args: any 125 | ) => infer R ? R : any 126 | 127 | type Func2 = (param: string) => string[] 128 | type FuncReturn = ReturnType // string[] -------------------------------------------------------------------------------- /gulp-demo/src/js/myAlbum.js: -------------------------------------------------------------------------------- 1 | window.onload = function(){ 2 | var x,y,nX,nY; 3 | var sumX = 0, sumY = 0; 4 | var page = document.querySelector(".page"); 5 | var album = document.querySelector(".album"); 6 | var change = document.querySelectorAll(".change"); 7 | var change2 = document.querySelectorAll(".change2"); 8 | 9 | /* 设置延时绑定事件,不影响开场动画 */ 10 | setTimeout(function(){ 11 | document.addEventListener("mousedown",start); 12 | },3000); 13 | 14 | /* 设置图片背景 */ 15 | var mainHold = document.querySelectorAll(".main-hold"); 16 | for(var i = 0;i<12;i++) { 17 | mainHold[i].setAttribute("style","background-image:url(./images/"+(i+1)+".jpg)"); 18 | } 19 | 20 | var top = document.querySelector(".top"); 21 | var bottom =document.querySelector(".bottom"); 22 | function start(event) { 23 | if(event.button == 0) { 24 | //阻止浏览器默认事件 25 | stopDefault(event); 26 | 27 | //使橙色方块隐藏 28 | top.setAttribute("style","animation:orange-hide 3s linear forwards"); 29 | bottom.setAttribute("style","animation:orange-hide 3s linear forwards"); 30 | 31 | 32 | nX = event.clientX; 33 | nY = event.clientY; 34 | document.addEventListener("mousemove",move); 35 | document.addEventListener("mouseup",end); 36 | } 37 | return false; 38 | } 39 | 40 | function move(event) { 41 | //设置绕Y轴旋转 42 | x = nX - event.clientX; 43 | sumX = sumX + 0.1*x; 44 | 45 | //设置绕X轴旋转 46 | y = nY - event.clientY; 47 | sumY = 0.1*y; 48 | 49 | /*划定边界*/ 50 | if(sumY >= 10) { 51 | sumY = 10; 52 | } 53 | else if(sumY <= -10){ 54 | sumY = -10; 55 | } 56 | 57 | album.setAttribute("style","transform: translateZ(460px) rotateY("+ sumX +"deg) rotate3d(100,0,0,"+ sumY +"deg)"); 58 | 59 | //保存当前clientX的值以便下次调用 60 | nX = event.clientX; 61 | 62 | //设置颜色变换 63 | change[0].setAttribute("style","animation-play-state:running"); 64 | change[1].setAttribute("style","animation-play-state:running"); 65 | change2[0].setAttribute("style","animation-play-state:running"); 66 | change2[1].setAttribute("style","animation-play-state:running"); 67 | 68 | return false; 69 | } 70 | 71 | function end() { 72 | album.setAttribute("style","transform: translateZ(460px) rotateY("+ sumX +"deg)"); 73 | 74 | //停止颜色变换 75 | change[0].setAttribute("style","animation-play-state:paused"); 76 | change[1].setAttribute("style","animation-play-state:paused"); 77 | change2[0].setAttribute("style","animation-play-state:paused"); 78 | change2[1].setAttribute("style","animation-play-state:paused"); 79 | 80 | 81 | document.removeEventListener("mousemove",move); 82 | document.removeEventListener("mouseup",end); 83 | } 84 | 85 | //阻止浏览器默认行为触发的通用方法 86 | function stopDefault(e){ 87 | //防止浏览器默认行为(W3C) 88 | if(e && e.preventDefault){ 89 | e.preventDefault(); 90 | } 91 | //IE中组织浏览器行为 92 | else{ 93 | window.event.returnValue=fale; 94 | return false; 95 | } 96 | } 97 | 98 | }; 99 | -------------------------------------------------------------------------------- /typescript/01-sample.ts: -------------------------------------------------------------------------------- 1 | /* =============== 原始数据类型 =============== */ 2 | const str: string = 'text' 3 | const num: number = 1 4 | const bool: boolean = true 5 | const undef: undefined = undefined 6 | const empty: null = null 7 | const symb: symbol = Symbol('symb') 8 | const bigint: bigint = BigInt(9007199254740993) 9 | 10 | /* object */ 11 | 12 | let demo: object 13 | demo = [] 14 | demo = {} 15 | demo = () => {} 16 | demo = 1 // Error: Type 'number' is not assignable to type 'object' 17 | 18 | /* =============== Object 与 {} =============== */ 19 | 20 | let demo1: Object 21 | demo1 = [] 22 | demo1 = {} 23 | demo1 = 1 24 | // null, undefined 需要在 strictNullChecks=false 时才可以 25 | demo1 = null 26 | demo1 = undefined 27 | 28 | let demo2: {} 29 | demo2 = [] 30 | demo2 = {} 31 | demo2 = 1 32 | demo2 = null // Error: Type 'null' is not assignable to type '{}' 33 | demo2 = undefined // Error: Type 'undefined' is not assignable to type '{}' 34 | 35 | 36 | /* =============== 数组 =============== */ 37 | 38 | const arr1: string[] = [] 39 | // 等价于 40 | const arr2: Array = [] 41 | 42 | /* =============== 元组 =============== */ 43 | 44 | const tup: [string, number] = ['LiHua', 18] 45 | 46 | // 支持可选 47 | const tup1: [string, number?] = ['LiHua'] 48 | // 支持对属性命名 49 | const tup2: [name: string, age?: number] = ['LiHua'] 50 | 51 | /* =============== 函数 =============== */ 52 | 53 | // 函数式声明 54 | function test1(x: number, y: number): number { 55 | return x + y 56 | } 57 | // 表达式声明 58 | const test2: (x: number, y: number) => number = (x, y) => { 59 | return x + y 60 | } 61 | // 或 62 | const test3 = (x: number, y: number): number => { 63 | return x + y 64 | } 65 | 66 | /* =============== void =============== */ 67 | 68 | 69 | // case 1 70 | function test4() {} 71 | 72 | // case 2 73 | function test5() { 74 | return; 75 | } 76 | 77 | // case 3 78 | function test6() { 79 | return undefined; 80 | } 81 | 82 | 83 | /* =============== any 与 unknown =============== */ 84 | 85 | let type1: any 86 | // 被任意类型赋值 87 | type1 = 1 88 | // 赋值给任意类型 89 | let type2: number = type1 90 | 91 | let type3: unknown 92 | // 被任意类型赋值 93 | type3 = 1 94 | // 赋值给任意类型 95 | let type4: number = type3 // Error: Type 'unknown' is not assignable to type 'number' 96 | 97 | 98 | 99 | let str1: unknown = 'string'; 100 | str1.slice(0, 1) // Error: Object is of type 'unknown'. 101 | 102 | let str2: any = 'string'; 103 | str2.slice(0, 1) // Success 104 | 105 | 106 | 107 | let str3: unknown = 'string'; 108 | // 1. 通过 as 类型断言 109 | (str3 as string).slice(0, 1) 110 | 111 | // 2. 通过 typeof 类型推断 112 | if (typeof str3 === 'string') { 113 | str3.slice(0, 1) 114 | } 115 | 116 | /* =============== never =============== */ 117 | 118 | // 1.抛出异常 119 | function test7(): never { 120 | throw new Error('err') 121 | } 122 | 123 | // 2. 死循环 124 | function test8(): never { 125 | while(true) {} 126 | } 127 | 128 | 129 | 130 | const checkValueType = (value: string | number) => { 131 | if (typeof value === 'string') { 132 | // do something 133 | } else if (typeof value === 'number') { 134 | // do something 135 | } else { 136 | const check: never = value 137 | // do something 138 | } 139 | } 140 | 141 | 142 | 143 | const checkValueType1 = (value: string | number | boolean) => { 144 | if (typeof value === 'string') { 145 | // do something 146 | } else if (typeof value === 'number') { 147 | // do something 148 | } else { 149 | const check: never = value // Error: Type 'boolean' is not assignable to type 'never'. 150 | // do something 151 | } 152 | } -------------------------------------------------------------------------------- /lazyLoad/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 31 | 32 | 33 | 34 | 35 |
    36 |
  • 37 |
  • 38 |
  • 39 |
  • 40 |
  • 41 |
  • 42 |
  • 43 |
  • 44 |
  • 45 |
  • 46 |
  • 47 |
  • 48 |
49 | 50 | 51 | 52 | 95 | 96 | -------------------------------------------------------------------------------- /gulp-demo/dist/css/public.css: -------------------------------------------------------------------------------- 1 | @keyframes closer{0%{transform:translateZ(-800px)}to{transform:translateZ(460px)}}@keyframes color{0%,to{background-color:#fff}50%{background-color:#868686}}@keyframes color2{0%,to{background-color:#868686}50%{background-color:#fff}}@keyframes orange-hide{0%{opacity:1}to{opacity:0}}body{margin:0;padding:0;font-family:"Microsoft Yahei"}.page,body,html{height:100%}.page{width:100%;overflow:hidden;background-color:#fff;perspective:550px;cursor:move}.page .album{position:relative;margin:0 auto;margin-top:40vh;transform-style:preserve-3d;text-align:center;width:800px;height:200px;animation:closer 3s ease;transform:translateZ(460px)}.page .album .gallery{width:100%;height:100%;position:absolute;left:0;top:0;backface-visibility:hidden;display:flex}.page .album .gallery.left{transform:rotateY(90deg) translateZ(-400px)}.page .album .gallery.current{transform:translateZ(-400px)}.page .album .gallery.right{transform:rotateY(-90deg) translateZ(-400px)}.page .album .gallery.back{transform:rotateY(180deg) translateZ(-400px)}.page .album .gallery.change{background-color:#fff;animation:color 8s linear infinite;animation-play-state:paused}.page .album .gallery.change2{background-color:#868686;animation:color2 8s linear infinite;animation-play-state:paused}.page .album .gallery .photo{flex:1;perspective:550px;height:100%;transform-style:preserve-3d}.page .album .gallery .photo .back-photo,.page .album .gallery .photo .main-photo{width:40%;height:90%;margin:10% auto 0;transform-style:preserve-3d}.page .album .gallery .photo .main-photo .top-hold{width:4px;height:10%;background-color:#000;margin:0 auto}.page .album .gallery .photo .main-photo .main-hold{width:100%;height:70%;background-repeat:no-repeat;background-size:cover}.page .album .gallery .photo .main-photo .bottom-hold{width:4px;height:25%;background-color:#000;margin:0 auto}.page .album .gallery .photo .main-photo .side-hold{width:20px;height:40px;background-color:#000;margin:0 auto}.page .album .gallery .photo .back-photo .center-back{width:100%;height:70%;background-color:#ccc}.page .album .gallery .photo .back-photo .bottom-back{height:15%;width:8px;background-color:#ccc;margin:0 auto}.page .album .gallery .photo .back-photo .side-back{height:35px;width:8px;background-color:#ccc;margin:0 auto;transform-origin:top}.page .album .gallery .photo.left-photo .side-hold{transform:translateY(-50%) rotateX(90deg) skew(-15deg)}.page .album .gallery .photo.left-photo .back-photo{transform:translateX(35%) translateY(-98%) translateZ(-30px)}.page .album .gallery .photo.left-photo .back-photo .side-back{transform:rotateX(90deg) skew(-43deg)}.page .album .gallery .photo.center-photo .side-hold{transform:translateY(-50%) rotateX(90deg)}.page .album .gallery .photo.center-photo .back-photo{transform:translateZ(-30px) translateY(-98%)}.page .album .gallery .photo.center-photo .back-photo .side-back{transform:rotateX(90deg)}.page .album .gallery .photo.right-photo .side-hold{transform:translateY(-50%) rotateX(90deg) skew(15deg)}.page .album .gallery .photo.right-photo .back-photo{transform:translateX(-35%) translateY(-98%) translateZ(-30px)}.page .album .gallery .photo.right-photo .back-photo .side-back{transform:rotateX(90deg) skew(43deg)}.page .album .bottom,.page .album .top{position:absolute;left:0;top:0;display:flex;width:100%;height:800px;perspective:none}.page .album .bottom .diamonds,.page .album .top .diamonds{flex:1;display:flex;flex-direction:column}.page .album .bottom .diamonds .diamond,.page .album .top .diamonds .diamond{flex:1}.page .album .bottom .diamonds .diamond .orange,.page .album .top .diamonds .diamond .orange{width:20px;height:30px;margin:43% auto 0;background-color:#ff8000}.page .album .bottom{transform:translateY(-180px) rotateX(90deg)}.page .album .top{transform:translateY(-200px) rotateX(90deg) translateZ(220px)} -------------------------------------------------------------------------------- /typescript/02-sample.ts: -------------------------------------------------------------------------------- 1 | /* =============== 字面量类型 =============== */ 2 | 3 | const num_literal: 1 | 2 = 1 4 | const str_literal: "text1" | "text2" = "text1" 5 | 6 | 7 | /* =============== 枚举 =============== */ 8 | 9 | enum TestEnum { 10 | key1 = 'value1', 11 | key2 = 2 12 | } 13 | 14 | // 常量枚举 15 | const enum TestEnum1 { 16 | key1 = 'value1', 17 | key2 = 2 18 | } 19 | const val = TestEnum1.key2 20 | 21 | 22 | /* =============== 接口 =============== */ 23 | 24 | // 可选 25 | interface Person { 26 | name: string 27 | addr?: string 28 | } 29 | 30 | /* =============== readonly =============== */ 31 | 32 | interface Person { 33 | name: string 34 | readonly age: number 35 | } 36 | 37 | const person: Person = { name: 'LiHua', age: 18 } 38 | person.age = 20 // Cannot assign to 'age' because it is a read-only property 39 | 40 | const list: readonly number[] = [1, 2] 41 | list.push(3) // Property 'push' does not exist on type 'readonly number[]'. 42 | list[0] = 2 // Index signature in type 'readonly number[]' only permits reading 43 | 44 | 45 | /* =============== 类型别名 =============== */ 46 | 47 | type Person1 = { 48 | name: string; 49 | readonly age: number; 50 | addr?: string; 51 | } 52 | 53 | 54 | /* =============== 定义对象与扩展 =============== */ 55 | 56 | type Person2 = { 57 | name: string 58 | } 59 | 60 | // 接口通过继承的方式实现类型扩展: 61 | interface Person3 extends Person2 { 62 | age: number 63 | } 64 | 65 | // 类型别名通过交叉类型的方式实现类型扩展: 66 | type Person4 = Person2 & { 67 | age: number 68 | } 69 | 70 | 71 | type str = string 72 | type num = number 73 | type union = string | number 74 | type tup = [string, number] 75 | 76 | 77 | /* =============== 类型合并 =============== */ 78 | 79 | interface Person5 { 80 | name: string 81 | } 82 | interface Person5 { 83 | age: string 84 | } 85 | let person1: Person5 // { name: string; age: string } 86 | type Person6 { 87 | name: string 88 | } 89 | // Error: Duplicate identifier 'Person2' 90 | type Person6 { 91 | age: string 92 | } 93 | 94 | 95 | /* =============== 索引签名问题 =============== */ 96 | interface Test1 { 97 | name: string 98 | } 99 | type Test2 = { 100 | name: string 101 | } 102 | const data1: Test1 = { name: 'name1' } 103 | const data2: Test2 = { name: 'name2' } 104 | interface PropType { 105 | [key: string]: string 106 | } 107 | let prop: PropType 108 | prop = data1 // Error: Type 'Test2' is not assignable to type 'PropType'. Index signature for type 'string' is missing in type 'Test2' 109 | prop = data2 // success 110 | 111 | 112 | /* =============== 联合类型 =============== */ 113 | const union: string | number = 'text' 114 | 115 | /* =============== 交叉类型 =============== */ 116 | interface A { 117 | field1: string 118 | } 119 | 120 | interface B { 121 | field2: number 122 | } 123 | 124 | const test9: A & B = { field1: 'text', field2: 1 }; 125 | 126 | /* =============== 类型不存在 =============== */ 127 | 128 | type A1 = number 129 | type B1 = string 130 | type Union = A1 & B1 // never 131 | 132 | 133 | /* =============== 同名属性交叉 =============== */ 134 | 135 | interface A2 { 136 | field1: string 137 | common: { 138 | fieldA: string 139 | } 140 | } 141 | 142 | interface B2 { 143 | field2: number 144 | common: { 145 | fieldB: number 146 | } 147 | } 148 | 149 | const fields: A2 & B2 = { 150 | field1: 'text1', 151 | field2: 1, 152 | common: { fieldA: 'text2', fieldB: 2 } 153 | } 154 | // success 155 | 156 | /* =============== 鸭子类型 =============== */ 157 | 158 | interface Param { 159 | field1: string 160 | } 161 | 162 | const func = (param: Param) => param 163 | func({ field1: '111', field2: 2 }) // Error 164 | 165 | const param1 = { field1: '111', field2: 2 } 166 | func(param1); // success 167 | 168 | 169 | /* =============== 类型断言 =============== */ 170 | 171 | 172 | interface Param { 173 | field1: string 174 | } 175 | 176 | const func1 = (param: Param) => param 177 | func1({ field1: '111', field2: 2 } as Param) // success 178 | 179 | 180 | 181 | const func2 = (str: string) => str 182 | const param = ['text1', 'text2'].find(str => str === 'text1') 183 | func2(param) // Error 184 | func2(param!) // success 185 | -------------------------------------------------------------------------------- /promise/src/promise4.js: -------------------------------------------------------------------------------- 1 | // 完整版 promise 2 | // 实现 promise/A+ 规范 3 | 4 | const STATE = { 5 | PENDING: 'pending', 6 | FULFILLED: 'fulfilled', 7 | REJECTED: 'rejected' 8 | } 9 | 10 | const generatePromise = (promise2, x, fulfill, reject) => { 11 | if (promise2 === x) { 12 | return reject(new TypeError('Chaining cycle detected for promise')) 13 | } 14 | // 如果 x 是 promise,调用它的 then 方法继续遍历 15 | if (x instanceof MyPromise) { 16 | x.then((value) => { 17 | generatePromise(promise2, value, fulfill, reject) 18 | }, (e) => { 19 | reject(e) 20 | }) 21 | } else if (x != null && (typeof x === 'object' || typeof x === 'function')) { 22 | // 防止重复调用,成功和失败只能调用一次 23 | let called; 24 | // 如果 x 是对象或函数 25 | try { 26 | const then = x.then 27 | if (typeof then === 'function') { 28 | then.call(x, (y) => { 29 | if (called) return; 30 | called = true; 31 | // 说明 y是 promise,继续遍历 32 | generatePromise(promise2, y, fulfill, reject) 33 | }, (r) => { 34 | if (called) return; 35 | called = true; 36 | reject(r) 37 | }) 38 | } else { 39 | fulfill(x) 40 | } 41 | } catch(e) { 42 | if (called) return 43 | called = true 44 | reject(e) 45 | } 46 | } else { 47 | fulfill(x) 48 | } 49 | } 50 | 51 | class MyPromise { 52 | constructor(fn) { 53 | // 初始化 54 | this.state = STATE.PENDING 55 | this.value = null 56 | this.reason = null 57 | // 保存数组 58 | this.fulfilledCallbacks = [] 59 | this.rejectedCallbacks = [] 60 | // 成功 61 | const fulfill = (value) => { 62 | // 只有 state 为 pending 时,才可以更改状态 63 | if (this.state === STATE.PENDING) { 64 | this.state = STATE.FULFILLED 65 | this.value = value 66 | this.fulfilledCallbacks.forEach(cb => cb()) 67 | } 68 | } 69 | 70 | // 失败 71 | const reject = (reason) => { 72 | if (this.state === STATE.PENDING) { 73 | this.state = STATE.REJECTED 74 | this.reason = reason 75 | this.rejectedCallbacks.forEach(cb => cb()) 76 | } 77 | } 78 | // 执行函数出错时调用 reject 79 | try { 80 | fn(fulfill, reject) 81 | } catch (e) { 82 | reject(e) 83 | } 84 | } 85 | 86 | then(onFulfilled, onRejected) { 87 | // Promises/A+ 规范规定: 88 | // 如果 onFulfilled 不是函数且 promise1 成功执行, promise2 必须成功执行并返回相同的值 89 | // 如果 onRejected 不是函数且 promise1 拒绝执行, promise2 必须拒绝执行并返回相同的拒因 90 | onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value 91 | onRejected = typeof onRejected === 'function' ? onRejected : e => { throw e } 92 | const promise2 = new MyPromise((fulfill, reject) => { 93 | // setTimeout 宏任务,确保onFulfilled 和 onRejected 异步执行 94 | if (this.state === STATE.FULFILLED) { 95 | setTimeout(() => { 96 | try { 97 | const x = onFulfilled(this.value) 98 | generatePromise(promise2, x, fulfill, reject) 99 | } catch (e) { 100 | reject(e) 101 | } 102 | }, 0) 103 | } 104 | if (this.state === STATE.REJECTED) { 105 | setTimeout(() => { 106 | try { 107 | const x = onRejected(this.reason) 108 | generatePromise(promise2, x, fulfill, reject) 109 | } catch (e) { 110 | reject(e) 111 | } 112 | }, 0) 113 | } 114 | // 当 then 是 pending 时,将这两个状态写入数组中 115 | if (this.state === STATE.PENDING) { 116 | this.fulfilledCallbacks.push(() => { 117 | setTimeout(() => { 118 | try { 119 | const x = onFulfilled(this.value) 120 | generatePromise(promise2, x, fulfill, reject) 121 | } catch(e) { 122 | reject(e) 123 | } 124 | }, 0) 125 | }) 126 | this.rejectedCallbacks.push(() => { 127 | setTimeout(() => { 128 | try { 129 | const x = onRejected(this.reason) 130 | generatePromise(promise2, x, fulfill, reject) 131 | } catch (e) { 132 | reject(e) 133 | } 134 | }, 0) 135 | }) 136 | } 137 | }) 138 | return promise2 139 | } 140 | } 141 | 142 | module.exports = MyPromise 143 | -------------------------------------------------------------------------------- /typescript/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@cspotcode/source-map-support@^0.8.0": 6 | version "0.8.1" 7 | resolved "http://bnpm.byted.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" 8 | integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== 9 | dependencies: 10 | "@jridgewell/trace-mapping" "0.3.9" 11 | 12 | "@jridgewell/resolve-uri@^3.0.3": 13 | version "3.1.0" 14 | resolved "http://bnpm.byted.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" 15 | integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== 16 | 17 | "@jridgewell/sourcemap-codec@^1.4.10": 18 | version "1.4.14" 19 | resolved "http://bnpm.byted.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" 20 | integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== 21 | 22 | "@jridgewell/trace-mapping@0.3.9": 23 | version "0.3.9" 24 | resolved "http://bnpm.byted.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" 25 | integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== 26 | dependencies: 27 | "@jridgewell/resolve-uri" "^3.0.3" 28 | "@jridgewell/sourcemap-codec" "^1.4.10" 29 | 30 | "@tsconfig/node10@^1.0.7": 31 | version "1.0.9" 32 | resolved "http://bnpm.byted.org/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" 33 | integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== 34 | 35 | "@tsconfig/node12@^1.0.7": 36 | version "1.0.11" 37 | resolved "http://bnpm.byted.org/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" 38 | integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== 39 | 40 | "@tsconfig/node14@^1.0.0": 41 | version "1.0.3" 42 | resolved "http://bnpm.byted.org/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" 43 | integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== 44 | 45 | "@tsconfig/node16@^1.0.2": 46 | version "1.0.3" 47 | resolved "http://bnpm.byted.org/@tsconfig/node16/-/node16-1.0.3.tgz#472eaab5f15c1ffdd7f8628bd4c4f753995ec79e" 48 | integrity sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ== 49 | 50 | acorn-walk@^8.1.1: 51 | version "8.2.0" 52 | resolved "http://bnpm.byted.org/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" 53 | integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== 54 | 55 | acorn@^8.4.1: 56 | version "8.8.0" 57 | resolved "http://bnpm.byted.org/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" 58 | integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== 59 | 60 | arg@^4.1.0: 61 | version "4.1.3" 62 | resolved "http://bnpm.byted.org/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" 63 | integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== 64 | 65 | create-require@^1.1.0: 66 | version "1.1.1" 67 | resolved "http://bnpm.byted.org/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" 68 | integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== 69 | 70 | diff@^4.0.1: 71 | version "4.0.2" 72 | resolved "http://bnpm.byted.org/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" 73 | integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== 74 | 75 | make-error@^1.1.1: 76 | version "1.3.6" 77 | resolved "http://bnpm.byted.org/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" 78 | integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== 79 | 80 | ts-node@^10.9.1: 81 | version "10.9.1" 82 | resolved "http://bnpm.byted.org/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" 83 | integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== 84 | dependencies: 85 | "@cspotcode/source-map-support" "^0.8.0" 86 | "@tsconfig/node10" "^1.0.7" 87 | "@tsconfig/node12" "^1.0.7" 88 | "@tsconfig/node14" "^1.0.0" 89 | "@tsconfig/node16" "^1.0.2" 90 | acorn "^8.4.1" 91 | acorn-walk "^8.1.1" 92 | arg "^4.1.0" 93 | create-require "^1.1.0" 94 | diff "^4.0.1" 95 | make-error "^1.1.1" 96 | v8-compile-cache-lib "^3.0.1" 97 | yn "3.1.1" 98 | 99 | typescript@^4.7.4: 100 | version "4.7.4" 101 | resolved "http://bnpm.byted.org/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" 102 | integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== 103 | 104 | v8-compile-cache-lib@^3.0.1: 105 | version "3.0.1" 106 | resolved "http://bnpm.byted.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" 107 | integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== 108 | 109 | yn@3.1.1: 110 | version "3.1.1" 111 | resolved "http://bnpm.byted.org/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" 112 | integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== 113 | -------------------------------------------------------------------------------- /gulp-demo/src/css/myAlbum.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: "Microsoft Yahei"; 5 | } 6 | body, 7 | html { 8 | height: 100%; 9 | } 10 | .page { 11 | width: 100%; 12 | height: 100%; 13 | overflow: hidden; 14 | background-color: #fff; 15 | perspective: 550px; 16 | cursor: move; 17 | } 18 | .page .album { 19 | position: relative; 20 | margin: 0 auto; 21 | margin-top: 40vh; 22 | transform-style: preserve-3d; 23 | text-align: center; 24 | width: 800px; 25 | height: 200px; 26 | animation: closer 3s ease; 27 | transform: translateZ(460px); 28 | } 29 | .page .album .gallery { 30 | width: 100%; 31 | height: 100%; 32 | position: absolute; 33 | left: 0; 34 | top: 0; 35 | backface-visibility: hidden; 36 | display: flex; 37 | } 38 | .page .album .gallery.left { 39 | transform: rotateY(90deg) translateZ(-400px); 40 | } 41 | .page .album .gallery.current { 42 | transform: translateZ(-400px); 43 | } 44 | .page .album .gallery.right { 45 | transform: rotateY(-90deg) translateZ(-400px); 46 | } 47 | .page .album .gallery.back { 48 | transform: rotateY(180deg) translateZ(-400px); 49 | } 50 | .page .album .gallery.change { 51 | background-color: #fff; 52 | animation: color 8s linear infinite; 53 | animation-play-state: paused; 54 | } 55 | .page .album .gallery.change2 { 56 | background-color: #868686; 57 | animation: color2 8s linear infinite; 58 | animation-play-state: paused; 59 | } 60 | .page .album .gallery .photo { 61 | flex: 1; 62 | perspective: 550px; 63 | height: 100%; 64 | transform-style: preserve-3d; 65 | } 66 | .page .album .gallery .photo .main-photo { 67 | width: 40%; 68 | height: 90%; 69 | margin: 0 auto; 70 | margin-top: 10%; 71 | transform-style: preserve-3d; 72 | } 73 | .page .album .gallery .photo .main-photo .top-hold { 74 | width: 4px; 75 | height: 10%; 76 | background-color: #000; 77 | margin: 0 auto; 78 | } 79 | .page .album .gallery .photo .main-photo .main-hold { 80 | width: 100%; 81 | height: 70%; 82 | background-repeat: no-repeat; 83 | background-size: cover; 84 | } 85 | .page .album .gallery .photo .main-photo .bottom-hold { 86 | width: 4px; 87 | height: 25%; 88 | background-color: #000; 89 | margin: 0 auto; 90 | } 91 | .page .album .gallery .photo .main-photo .side-hold { 92 | width: 20px; 93 | height: 40px; 94 | background-color: #000; 95 | margin: 0 auto; 96 | /* transform-style: preserve-3d; 97 | position: relative; */ 98 | } 99 | .page .album .gallery .photo .back-photo { 100 | width: 40%; 101 | height: 90%; 102 | margin: 0 auto; 103 | margin-top: 10%; 104 | transform-style: preserve-3d; 105 | } 106 | .page .album .gallery .photo .back-photo .center-back { 107 | width: 100%; 108 | height: 70%; 109 | background-color: #ccc; 110 | } 111 | .page .album .gallery .photo .back-photo .bottom-back { 112 | height: 15%; 113 | width: 8px; 114 | background-color: #ccc; 115 | margin: 0 auto; 116 | } 117 | .page .album .gallery .photo .back-photo .side-back { 118 | height: 35px; 119 | width: 8px; 120 | background-color: #ccc; 121 | margin: 0 auto; 122 | transform-origin: top; 123 | } 124 | .page .album .gallery .photo.left-photo .side-hold { 125 | transform: translateY(-50%) rotateX(90deg) skew(-15deg); 126 | } 127 | .page .album .gallery .photo.left-photo .back-photo { 128 | transform: translateX(35%) translateY(-98%) translateZ(-30px); 129 | } 130 | .page .album .gallery .photo.left-photo .back-photo .side-back { 131 | transform: rotateX(90deg) skew(-43deg); 132 | } 133 | .page .album .gallery .photo.center-photo .side-hold { 134 | transform: translateY(-50%) rotateX(90deg); 135 | } 136 | .page .album .gallery .photo.center-photo .back-photo { 137 | transform: translateZ(-30px) translateY(-98%); 138 | } 139 | .page .album .gallery .photo.center-photo .back-photo .side-back { 140 | transform: rotateX(90deg); 141 | } 142 | .page .album .gallery .photo.right-photo .side-hold { 143 | transform: translateY(-50%) rotateX(90deg) skew(15deg); 144 | } 145 | .page .album .gallery .photo.right-photo .back-photo { 146 | transform: translateX(-35%) translateY(-98%) translateZ(-30px); 147 | } 148 | .page .album .gallery .photo.right-photo .back-photo .side-back { 149 | transform: rotateX(90deg) skew(43deg); 150 | } 151 | .page .album .top, 152 | .page .album .bottom { 153 | position: absolute; 154 | left: 0; 155 | top: 0; 156 | display: flex; 157 | width: 100%; 158 | height: 800px; 159 | perspective: none; 160 | } 161 | .page .album .top .diamonds, 162 | .page .album .bottom .diamonds { 163 | flex: 1; 164 | display: flex; 165 | flex-direction: column; 166 | } 167 | .page .album .top .diamonds .diamond, 168 | .page .album .bottom .diamonds .diamond { 169 | flex: 1; 170 | } 171 | .page .album .top .diamonds .diamond .orange, 172 | .page .album .bottom .diamonds .diamond .orange { 173 | width: 20px; 174 | height: 30px; 175 | margin: 0 auto; 176 | margin-top: 43%; 177 | background-color: #ff8000; 178 | } 179 | .page .album .bottom { 180 | transform: translateY(-180px) rotateX(90deg); 181 | } 182 | .page .album .top { 183 | transform: translateY(-200px) rotateX(90deg) translateZ(220px); 184 | } 185 | @keyframes closer { 186 | 0% { 187 | transform: translateZ(-800px); 188 | } 189 | 100% { 190 | transform: translateZ(460px); 191 | } 192 | } 193 | @keyframes color { 194 | 0% { 195 | background-color: #fff; 196 | } 197 | 50% { 198 | background-color: #868686; 199 | } 200 | 100% { 201 | background-color: #fff; 202 | } 203 | } 204 | @keyframes color2 { 205 | 0% { 206 | background-color: #868686; 207 | } 208 | 50% { 209 | background-color: #fff; 210 | } 211 | 100% { 212 | background-color: #868686; 213 | } 214 | } 215 | @keyframes orange-hide { 216 | 0% { 217 | opacity: 1; 218 | } 219 | 100% { 220 | opacity: 0; 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /gulp-demo/dist/css/public-5c001c53f6.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: "Microsoft Yahei"; 5 | } 6 | body, 7 | html { 8 | height: 100%; 9 | } 10 | .page { 11 | width: 100%; 12 | height: 100%; 13 | overflow: hidden; 14 | background-color: #fff; 15 | perspective: 550px; 16 | cursor: move; 17 | } 18 | .page .album { 19 | position: relative; 20 | margin: 0 auto; 21 | margin-top: 40vh; 22 | transform-style: preserve-3d; 23 | text-align: center; 24 | width: 800px; 25 | height: 200px; 26 | animation: closer 3s ease; 27 | transform: translateZ(460px); 28 | } 29 | .page .album .gallery { 30 | width: 100%; 31 | height: 100%; 32 | position: absolute; 33 | left: 0; 34 | top: 0; 35 | backface-visibility: hidden; 36 | display: flex; 37 | } 38 | .page .album .gallery.left { 39 | transform: rotateY(90deg) translateZ(-400px); 40 | } 41 | .page .album .gallery.current { 42 | transform: translateZ(-400px); 43 | } 44 | .page .album .gallery.right { 45 | transform: rotateY(-90deg) translateZ(-400px); 46 | } 47 | .page .album .gallery.back { 48 | transform: rotateY(180deg) translateZ(-400px); 49 | } 50 | .page .album .gallery.change { 51 | background-color: #fff; 52 | animation: color 8s linear infinite; 53 | animation-play-state: paused; 54 | } 55 | .page .album .gallery.change2 { 56 | background-color: #868686; 57 | animation: color2 8s linear infinite; 58 | animation-play-state: paused; 59 | } 60 | .page .album .gallery .photo { 61 | flex: 1; 62 | perspective: 550px; 63 | height: 100%; 64 | transform-style: preserve-3d; 65 | } 66 | .page .album .gallery .photo .main-photo { 67 | width: 40%; 68 | height: 90%; 69 | margin: 0 auto; 70 | margin-top: 10%; 71 | transform-style: preserve-3d; 72 | } 73 | .page .album .gallery .photo .main-photo .top-hold { 74 | width: 4px; 75 | height: 10%; 76 | background-color: #000; 77 | margin: 0 auto; 78 | } 79 | .page .album .gallery .photo .main-photo .main-hold { 80 | width: 100%; 81 | height: 70%; 82 | background-repeat: no-repeat; 83 | background-size: cover; 84 | } 85 | .page .album .gallery .photo .main-photo .bottom-hold { 86 | width: 4px; 87 | height: 25%; 88 | background-color: #000; 89 | margin: 0 auto; 90 | } 91 | .page .album .gallery .photo .main-photo .side-hold { 92 | width: 20px; 93 | height: 40px; 94 | background-color: #000; 95 | margin: 0 auto; 96 | /* transform-style: preserve-3d; 97 | position: relative; */ 98 | } 99 | .page .album .gallery .photo .back-photo { 100 | width: 40%; 101 | height: 90%; 102 | margin: 0 auto; 103 | margin-top: 10%; 104 | transform-style: preserve-3d; 105 | } 106 | .page .album .gallery .photo .back-photo .center-back { 107 | width: 100%; 108 | height: 70%; 109 | background-color: #ccc; 110 | } 111 | .page .album .gallery .photo .back-photo .bottom-back { 112 | height: 15%; 113 | width: 8px; 114 | background-color: #ccc; 115 | margin: 0 auto; 116 | } 117 | .page .album .gallery .photo .back-photo .side-back { 118 | height: 35px; 119 | width: 8px; 120 | background-color: #ccc; 121 | margin: 0 auto; 122 | transform-origin: top; 123 | } 124 | .page .album .gallery .photo.left-photo .side-hold { 125 | transform: translateY(-50%) rotateX(90deg) skew(-15deg); 126 | } 127 | .page .album .gallery .photo.left-photo .back-photo { 128 | transform: translateX(35%) translateY(-98%) translateZ(-30px); 129 | } 130 | .page .album .gallery .photo.left-photo .back-photo .side-back { 131 | transform: rotateX(90deg) skew(-43deg); 132 | } 133 | .page .album .gallery .photo.center-photo .side-hold { 134 | transform: translateY(-50%) rotateX(90deg); 135 | } 136 | .page .album .gallery .photo.center-photo .back-photo { 137 | transform: translateZ(-30px) translateY(-98%); 138 | } 139 | .page .album .gallery .photo.center-photo .back-photo .side-back { 140 | transform: rotateX(90deg); 141 | } 142 | .page .album .gallery .photo.right-photo .side-hold { 143 | transform: translateY(-50%) rotateX(90deg) skew(15deg); 144 | } 145 | .page .album .gallery .photo.right-photo .back-photo { 146 | transform: translateX(-35%) translateY(-98%) translateZ(-30px); 147 | } 148 | .page .album .gallery .photo.right-photo .back-photo .side-back { 149 | transform: rotateX(90deg) skew(43deg); 150 | } 151 | .page .album .top, 152 | .page .album .bottom { 153 | position: absolute; 154 | left: 0; 155 | top: 0; 156 | display: flex; 157 | width: 100%; 158 | height: 800px; 159 | perspective: none; 160 | } 161 | .page .album .top .diamonds, 162 | .page .album .bottom .diamonds { 163 | flex: 1; 164 | display: flex; 165 | flex-direction: column; 166 | } 167 | .page .album .top .diamonds .diamond, 168 | .page .album .bottom .diamonds .diamond { 169 | flex: 1; 170 | } 171 | .page .album .top .diamonds .diamond .orange, 172 | .page .album .bottom .diamonds .diamond .orange { 173 | width: 20px; 174 | height: 30px; 175 | margin: 0 auto; 176 | margin-top: 43%; 177 | background-color: #ff8000; 178 | } 179 | .page .album .bottom { 180 | transform: translateY(-180px) rotateX(90deg); 181 | } 182 | .page .album .top { 183 | transform: translateY(-200px) rotateX(90deg) translateZ(220px); 184 | } 185 | @keyframes closer { 186 | 0% { 187 | transform: translateZ(-800px); 188 | } 189 | 100% { 190 | transform: translateZ(460px); 191 | } 192 | } 193 | @keyframes color { 194 | 0% { 195 | background-color: #fff; 196 | } 197 | 50% { 198 | background-color: #868686; 199 | } 200 | 100% { 201 | background-color: #fff; 202 | } 203 | } 204 | @keyframes color2 { 205 | 0% { 206 | background-color: #868686; 207 | } 208 | 50% { 209 | background-color: #fff; 210 | } 211 | 100% { 212 | background-color: #868686; 213 | } 214 | } 215 | @keyframes orange-hide { 216 | 0% { 217 | opacity: 1; 218 | } 219 | 100% { 220 | opacity: 0; 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /promise/src/promise5.js: -------------------------------------------------------------------------------- 1 | // 完整版 promise 2 | // 实现 promise 链式调用、异步执行 3 | // 实现 catch、finally 4 | // 实现 resolve、reject、race、all 5 | 6 | const STATE = { 7 | PENDING: 'pending', 8 | FULFILLED: 'fulfilled', 9 | REJECTED: 'rejected' 10 | } 11 | 12 | class MyPromise { 13 | constructor(fn) { 14 | // 初始化 15 | this.state = STATE.PENDING 16 | this.value = null 17 | this.reason = null 18 | // 保存数组 19 | this.fulfilledCallbacks = [] 20 | this.rejectedCallbacks = [] 21 | // 成功 22 | const fulfill = (value) => { 23 | // 只有 state 为 pending 时,才可以更改状态 24 | if (this.state === STATE.PENDING) { 25 | this.state = STATE.FULFILLED 26 | this.value = value 27 | this.fulfilledCallbacks.forEach(cb => cb()) 28 | } 29 | } 30 | 31 | // 失败 32 | const reject = (reason) => { 33 | if (this.state === STATE.PENDING) { 34 | this.state = STATE.REJECTED 35 | this.reason = reason 36 | this.rejectedCallbacks.forEach(cb => cb()) 37 | } 38 | } 39 | // 执行函数出错时调用 reject 40 | try { 41 | fn(fulfill, reject) 42 | } catch (e) { 43 | reject(e) 44 | } 45 | } 46 | 47 | then(onFulfilled, onRejected) { 48 | // Promises/A+ 规范规定: 49 | // 如果 onFulfilled 不是函数且 promise1 成功执行, promise2 必须成功执行并返回相同的值 50 | // 如果 onRejected 不是函数且 promise1 拒绝执行, promise2 必须拒绝执行并返回相同的拒因 51 | onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value 52 | onRejected = typeof onRejected === 'function' ? onRejected : e => { throw e } 53 | const promise2 = new MyPromise((fulfill, reject) => { 54 | // setTimeout 宏任务,确保onFulfilled 和 onRejected 异步执行 55 | setTimeout(() => { 56 | if (this.state === STATE.FULFILLED) { 57 | try { 58 | const x = onFulfilled(this.value) 59 | generatePromise(promise2, x, fulfill, reject) 60 | } catch (e) { 61 | reject(e) 62 | } 63 | } 64 | if (this.state === STATE.REJECTED) { 65 | try { 66 | const x = onRejected(this.reason) 67 | generatePromise(promise2, x, fulfill, reject) 68 | } catch (e) { 69 | reject(e) 70 | } 71 | } 72 | // 当 then 是 pending 时,将这两个状态写入数组中 73 | if (this.state === STATE.PENDING) { 74 | this.fulfilledCallbacks.push(() => { 75 | const x = onFulfilled(this.value) 76 | generatePromise(promise2, x, fulfill, reject) 77 | }) 78 | this.rejectedCallbacks.push(() => { 79 | try { 80 | const x = onRejected(this.reason) 81 | generatePromise(promise2, x, fulfill, reject) 82 | } catch (e) { 83 | reject(e) 84 | } 85 | }) 86 | } 87 | }, 0) 88 | }) 89 | return promise2 90 | } 91 | catch(onRejected) { 92 | return this.then(null, onRejected) 93 | } 94 | finally(callback) { 95 | return this.then(callback, callback) 96 | } 97 | } 98 | 99 | function generatePromise(promise2, x, fulfill, reject) { 100 | if (promise2 === x) { 101 | return reject(new TypeError('Chaining cycle detected for promise')) 102 | } 103 | // 如果 x 是 promise,继续遍历 104 | if (x instanceof MyPromise) { 105 | x.then((value) => { 106 | generatePromise(promise2, value, fulfill, reject) 107 | }, (e) => { 108 | reject(e) 109 | }) 110 | } else if (x != null && (typeof x === 'object' || typeof x === 'function')) { 111 | // 防止重复调用,成功和失败只能调用一次 112 | let called; 113 | // 如果 x 是对象或函数 114 | try { 115 | const then = x.then 116 | if (typeof then === 'function') { 117 | then.call(x, (y) => { 118 | if (called) return; 119 | called = true; 120 | // 说明 y是 promise,继续遍历 121 | generatePromise(promise2, y, fulfill, reject) 122 | }, (r) => { 123 | if (called) return; 124 | called = true; 125 | reject(r) 126 | }) 127 | } else { 128 | fulfill(x) 129 | } 130 | } catch(e) { 131 | if (called) return 132 | called = true 133 | reject(e) 134 | } 135 | } else { 136 | fulfill(x) 137 | } 138 | } 139 | 140 | MyPromise.resolve = (value) => { 141 | // 传入 promise 类型直接返回 142 | if (value instanceof MyPromise) return value 143 | // 传入 thenable 对象时,立即执行 then 方法 144 | if (value !== null && typeof value === 'object') { 145 | const then = value.then 146 | if (then && typeof then === 'function') return new MyPromise(value.then) 147 | } 148 | return new MyPromise((resolve) => { 149 | resolve(value) 150 | }) 151 | } 152 | 153 | MyPromise.reject = (reason) => { 154 | // 传入 promise 类型直接返回 155 | if (reason instanceof MyPromise) return reason 156 | return new MyPromise((resolve, reject) => { 157 | reject(reason) 158 | }) 159 | } 160 | 161 | MyPromise.race = (promises) => { 162 | return new MyPromise((resolve, reject) => { 163 | // promises 可以不是数组,但必须存在 Iterator 接口,因此采用 for...of 遍历 164 | for(let promise of promises) { 165 | // 如果当前值不是 Promise,通过 resolve 方法转为 promise 166 | if (promise instanceof MyPromise) { 167 | promise.then(resolve, reject) 168 | } else { 169 | MyPromise.resolve(promise).then(resolve, reject) 170 | } 171 | } 172 | }) 173 | } 174 | 175 | MyPromise.all = (promises) => { 176 | return new MyPromise((resolve, reject) => { 177 | const arr = [] 178 | // 已返回数 179 | let count = 0 180 | // 当前索引 181 | let index = 0 182 | // promises 可以不是数组,但必须存在 Iterator 接口,因此采用 for...of 遍历 183 | for(let promise of promises) { 184 | // 如果当前值不是 Promise,通过 resolve 方法转为 promise 185 | if (!(promise instanceof MyPromise)) { 186 | promise = MyPromise.resolve(promise) 187 | } 188 | // 使用闭包保证异步返回数组顺序 189 | ((i) => { 190 | promise.then((value) => { 191 | arr[i] = value 192 | count += 1 193 | if (count === promises.length || count === promises.size) { 194 | resolve(arr) 195 | } 196 | }, reject) 197 | })(index) 198 | // index 递增 199 | index += 1 200 | } 201 | }) 202 | } 203 | 204 | MyPromise.allSettled = (promises) => { 205 | return new MyPromise((resolve, reject) => { 206 | const arr = [] 207 | // 已返回数 208 | let count = 0 209 | // 当前索引 210 | let index = 0 211 | // promises 可以不是数组,但必须存在 Iterator 接口,因此采用 for...of 遍历 212 | for(let promise of promises) { 213 | // 如果当前值不是 Promise,通过 resolve 方法转为 promise 214 | if (!(promise instanceof MyPromise)) { 215 | promise = MyPromise.resolve(promise) 216 | } 217 | // 使用闭包保证异步返回数组顺序 218 | ((i) => { 219 | promise.then((value) => { 220 | arr[i] = value 221 | count += 1 222 | if (count === promises.length || count === promises.size) { 223 | resolve(arr) 224 | } 225 | }, (err) => { 226 | arr[i] = err 227 | count += 1 228 | if (count === promises.length || count === promises.size) { 229 | resolve(arr) 230 | } 231 | }) 232 | })(index) 233 | // index 递增 234 | index += 1 235 | } 236 | }) 237 | } 238 | 239 | module.exports = MyPromise -------------------------------------------------------------------------------- /gulp-demo/src/less/myAlbum.less: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: "Microsoft Yahei"; 5 | } 6 | 7 | body,html { 8 | height: 100%; 9 | } 10 | 11 | .page { 12 | width: 100%; 13 | height: 100%; 14 | overflow: hidden; 15 | background-color: #fff; 16 | perspective: 550px; 17 | cursor: move; 18 | .album { 19 | position: relative; 20 | margin: 0 auto; 21 | margin-top: 40vh; 22 | transform-style: preserve-3d; 23 | text-align: center; 24 | width: 800px; 25 | height: 200px; 26 | animation: closer 3s ease; 27 | 28 | transform: translateZ(460px); 29 | .gallery { 30 | width: 100%; 31 | height: 100%; 32 | position: absolute; 33 | left: 0; 34 | top: 0; 35 | backface-visibility: hidden; 36 | display: flex; 37 | &.left { 38 | transform: rotateY(90deg) translateZ(-400px); 39 | } 40 | &.current { 41 | transform: translateZ(-400px); 42 | } 43 | &.right { 44 | transform: rotateY(-90deg) translateZ(-400px); 45 | } 46 | &.back { 47 | transform: rotateY(180deg) translateZ(-400px); 48 | } 49 | &.change { 50 | background-color: #fff; 51 | animation: color 8s linear infinite; 52 | animation-play-state: paused; 53 | } 54 | &.change2 { 55 | background-color: #868686; 56 | animation: color2 8s linear infinite; 57 | animation-play-state: paused; 58 | } 59 | .photo{ 60 | flex: 1; 61 | perspective: 550px; 62 | height: 100%; 63 | transform-style: preserve-3d; 64 | 65 | .main-photo { 66 | width: 40%; 67 | height: 90%; 68 | margin:0 auto; 69 | margin-top: 10%; 70 | transform-style: preserve-3d; 71 | .top-hold { 72 | width: 4px; 73 | height: 10%; 74 | background-color: #000; 75 | margin: 0 auto; 76 | } 77 | 78 | .main-hold { 79 | width: 100%; 80 | height: 70%; 81 | background-repeat: no-repeat; 82 | background-size: cover; 83 | } 84 | 85 | .bottom-hold { 86 | width: 4px; 87 | height: 25%; 88 | background-color: #000; 89 | margin: 0 auto; 90 | } 91 | 92 | .side-hold { 93 | width: 20px; 94 | height: 40px; 95 | background-color: #000; 96 | margin: 0 auto; 97 | /* transform-style: preserve-3d; 98 | position: relative; */ 99 | } 100 | } 101 | 102 | .back-photo { 103 | width: 40%; 104 | height: 90%; 105 | margin:0 auto; 106 | margin-top: 10%; 107 | transform-style: preserve-3d; 108 | .center-back { 109 | width: 100%; 110 | height: 70%; 111 | background-color: #ccc; 112 | } 113 | 114 | .bottom-back { 115 | height: 15%; 116 | width: 8px; 117 | background-color: #ccc; 118 | margin: 0 auto; 119 | } 120 | 121 | .side-back { 122 | height: 35px; 123 | width: 8px; 124 | background-color: #ccc; 125 | margin: 0 auto; 126 | transform-origin: top; 127 | } 128 | } 129 | 130 | &.left-photo { 131 | .side-hold { 132 | transform: translateY(-50%) rotateX(90deg) skew(-15deg); 133 | } 134 | .back-photo { 135 | transform: translateX(35%) translateY(-98%) translateZ(-30px); 136 | .side-back { 137 | transform: rotateX(90deg) skew(-43deg); 138 | } 139 | } 140 | } 141 | 142 | &.center-photo { 143 | .side-hold { 144 | transform: translateY(-50%) rotateX(90deg); 145 | } 146 | .back-photo { 147 | transform: translateZ(-30px) translateY(-98%); 148 | .side-back { 149 | transform: rotateX(90deg); 150 | } 151 | } 152 | } 153 | 154 | &.right-photo { 155 | .side-hold { 156 | transform: translateY(-50%) rotateX(90deg) skew(15deg); 157 | } 158 | .back-photo { 159 | transform: translateX(-35%) translateY(-98%) translateZ(-30px); 160 | .side-back { 161 | transform: rotateX(90deg) skew(43deg); 162 | } 163 | } 164 | } 165 | } 166 | } 167 | .top, 168 | .bottom { 169 | position: absolute; 170 | left: 0; 171 | top: 0; 172 | display: flex; 173 | width: 100%; 174 | height: 800px; 175 | perspective: none; 176 | .diamonds { 177 | flex: 1; 178 | display: flex; 179 | flex-direction: column; 180 | .diamond { 181 | flex: 1; 182 | .orange { 183 | width: 20px; 184 | height: 30px; 185 | margin: 0 auto; 186 | margin-top: 43%; 187 | background-color: #ff8000; 188 | } 189 | } 190 | } 191 | } 192 | .bottom { 193 | transform: translateY(-180px) rotateX(90deg); 194 | } 195 | 196 | .top { 197 | transform: translateY(-200px) rotateX(90deg) translateZ(220px); 198 | } 199 | } 200 | } 201 | 202 | @keyframes closer { 203 | 0% { 204 | transform: translateZ(-800px); 205 | } 206 | 207 | 100% { 208 | transform: translateZ(460px); 209 | } 210 | } 211 | 212 | @keyframes color { 213 | 0% { 214 | background-color: #fff; 215 | } 216 | 217 | 50% { 218 | background-color: #868686; 219 | } 220 | 221 | 100% { 222 | background-color: #fff; 223 | } 224 | } 225 | 226 | @keyframes color2 { 227 | 0% { 228 | background-color: #868686; 229 | } 230 | 231 | 50% { 232 | background-color: #fff; 233 | } 234 | 235 | 100% { 236 | background-color: #868686; 237 | } 238 | } 239 | 240 | @keyframes orange-hide { 241 | 0% { 242 | opacity: 1; 243 | } 244 | 100% { 245 | opacity: 0; 246 | } 247 | } -------------------------------------------------------------------------------- /promise/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "promise", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "commander": { 8 | "version": "2.3.0", 9 | "resolved": "https://registry.npm.taobao.org/commander/download/commander-2.3.0.tgz", 10 | "integrity": "sha1-/UMOiJgy7DU7ms0d4hfBHLPu+HM=", 11 | "dev": true 12 | }, 13 | "debug": { 14 | "version": "2.2.0", 15 | "resolved": "http://registry.npm.taobao.org/debug/download/debug-2.2.0.tgz", 16 | "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", 17 | "dev": true, 18 | "requires": { 19 | "ms": "0.7.1" 20 | } 21 | }, 22 | "diff": { 23 | "version": "1.4.0", 24 | "resolved": "https://registry.npm.taobao.org/diff/download/diff-1.4.0.tgz?cache=0&sync_timestamp=1578890967183&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fdiff%2Fdownload%2Fdiff-1.4.0.tgz", 25 | "integrity": "sha1-fyjS657nsVqX79ic5j3P2qPMur8=", 26 | "dev": true 27 | }, 28 | "escape-string-regexp": { 29 | "version": "1.0.2", 30 | "resolved": "https://registry.npm.taobao.org/escape-string-regexp/download/escape-string-regexp-1.0.2.tgz", 31 | "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=", 32 | "dev": true 33 | }, 34 | "formatio": { 35 | "version": "1.1.1", 36 | "resolved": "https://registry.npm.taobao.org/formatio/download/formatio-1.1.1.tgz", 37 | "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=", 38 | "dev": true, 39 | "requires": { 40 | "samsam": "~1.1" 41 | } 42 | }, 43 | "glob": { 44 | "version": "3.2.11", 45 | "resolved": "https://registry.npm.taobao.org/glob/download/glob-3.2.11.tgz", 46 | "integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=", 47 | "dev": true, 48 | "requires": { 49 | "inherits": "2", 50 | "minimatch": "0.3" 51 | } 52 | }, 53 | "growl": { 54 | "version": "1.9.2", 55 | "resolved": "https://registry.npm.taobao.org/growl/download/growl-1.9.2.tgz", 56 | "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", 57 | "dev": true 58 | }, 59 | "inherits": { 60 | "version": "2.0.4", 61 | "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Finherits%2Fdownload%2Finherits-2.0.4.tgz", 62 | "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", 63 | "dev": true 64 | }, 65 | "is-arguments": { 66 | "version": "1.0.4", 67 | "resolved": "https://registry.npm.taobao.org/is-arguments/download/is-arguments-1.0.4.tgz", 68 | "integrity": "sha1-P6+WbHy6D/Q3+zH2JQCC/PBEjPM=", 69 | "dev": true 70 | }, 71 | "is-generator-function": { 72 | "version": "1.0.7", 73 | "resolved": "https://registry.npm.taobao.org/is-generator-function/download/is-generator-function-1.0.7.tgz", 74 | "integrity": "sha1-0hMuUpuwAAp/gHlNS99c1eWBNSI=", 75 | "dev": true 76 | }, 77 | "jade": { 78 | "version": "0.26.3", 79 | "resolved": "https://registry.npm.taobao.org/jade/download/jade-0.26.3.tgz", 80 | "integrity": "sha1-jxDXl32NefL2/4YqgbBRPMslaGw=", 81 | "dev": true, 82 | "requires": { 83 | "commander": "0.6.1", 84 | "mkdirp": "0.3.0" 85 | }, 86 | "dependencies": { 87 | "commander": { 88 | "version": "0.6.1", 89 | "resolved": "https://registry.npm.taobao.org/commander/download/commander-0.6.1.tgz", 90 | "integrity": "sha1-+mihT2qUXVTbvlDYzbMyDp47GgY=", 91 | "dev": true 92 | }, 93 | "mkdirp": { 94 | "version": "0.3.0", 95 | "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.3.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.3.0.tgz", 96 | "integrity": "sha1-G79asbqCevI1dRQ0kEJkVfSB/h4=", 97 | "dev": true 98 | } 99 | } 100 | }, 101 | "lolex": { 102 | "version": "1.3.2", 103 | "resolved": "https://registry.npm.taobao.org/lolex/download/lolex-1.3.2.tgz", 104 | "integrity": "sha1-fD2mL/yzDw9agKJWbKJORdigHzE=", 105 | "dev": true 106 | }, 107 | "lru-cache": { 108 | "version": "2.7.3", 109 | "resolved": "http://registry.npm.taobao.org/lru-cache/download/lru-cache-2.7.3.tgz", 110 | "integrity": "sha1-bUUk6LlV+V1PW1iFHOId1y+06VI=", 111 | "dev": true 112 | }, 113 | "minimatch": { 114 | "version": "0.3.0", 115 | "resolved": "http://registry.npm.taobao.org/minimatch/download/minimatch-0.3.0.tgz", 116 | "integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=", 117 | "dev": true, 118 | "requires": { 119 | "lru-cache": "2", 120 | "sigmund": "~1.0.0" 121 | } 122 | }, 123 | "minimist": { 124 | "version": "0.0.8", 125 | "resolved": "https://registry.npm.taobao.org/minimist/download/minimist-0.0.8.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fminimist%2Fdownload%2Fminimist-0.0.8.tgz", 126 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 127 | "dev": true 128 | }, 129 | "mkdirp": { 130 | "version": "0.5.1", 131 | "resolved": "https://registry.npm.taobao.org/mkdirp/download/mkdirp-0.5.1.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmkdirp%2Fdownload%2Fmkdirp-0.5.1.tgz", 132 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 133 | "dev": true, 134 | "requires": { 135 | "minimist": "0.0.8" 136 | } 137 | }, 138 | "mocha": { 139 | "version": "2.5.3", 140 | "resolved": "https://registry.npm.taobao.org/mocha/download/mocha-2.5.3.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fmocha%2Fdownload%2Fmocha-2.5.3.tgz", 141 | "integrity": "sha1-FhvlvetJZ3HrmzV0UFC2IrWu/Fg=", 142 | "dev": true, 143 | "requires": { 144 | "commander": "2.3.0", 145 | "debug": "2.2.0", 146 | "diff": "1.4.0", 147 | "escape-string-regexp": "1.0.2", 148 | "glob": "3.2.11", 149 | "growl": "1.9.2", 150 | "jade": "0.26.3", 151 | "mkdirp": "0.5.1", 152 | "supports-color": "1.2.0", 153 | "to-iso-string": "0.0.2" 154 | } 155 | }, 156 | "ms": { 157 | "version": "0.7.1", 158 | "resolved": "https://registry.npm.taobao.org/ms/download/ms-0.7.1.tgz", 159 | "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", 160 | "dev": true 161 | }, 162 | "promises-aplus-tests": { 163 | "version": "2.1.2", 164 | "resolved": "https://registry.npm.taobao.org/promises-aplus-tests/download/promises-aplus-tests-2.1.2.tgz", 165 | "integrity": "sha1-drfFY4locghhlpz7zYeVr9J0iFw=", 166 | "dev": true, 167 | "requires": { 168 | "mocha": "^2.5.3", 169 | "sinon": "^1.10.3", 170 | "underscore": "~1.8.3" 171 | } 172 | }, 173 | "safe-buffer": { 174 | "version": "5.2.0", 175 | "resolved": "https://registry.npm.taobao.org/safe-buffer/download/safe-buffer-5.2.0.tgz?cache=0&sync_timestamp=1562377642757&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsafe-buffer%2Fdownload%2Fsafe-buffer-5.2.0.tgz", 176 | "integrity": "sha1-t02uxJsRSPiMZLaNSbHoFcHy9Rk=", 177 | "dev": true 178 | }, 179 | "samsam": { 180 | "version": "1.1.2", 181 | "resolved": "https://registry.npm.taobao.org/samsam/download/samsam-1.1.2.tgz", 182 | "integrity": "sha1-vsEf3IOp/aBjQBIQ5AF2wwJNFWc=", 183 | "dev": true 184 | }, 185 | "sigmund": { 186 | "version": "1.0.1", 187 | "resolved": "http://registry.npm.taobao.org/sigmund/download/sigmund-1.0.1.tgz", 188 | "integrity": "sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=", 189 | "dev": true 190 | }, 191 | "sinon": { 192 | "version": "1.17.7", 193 | "resolved": "https://registry.npm.taobao.org/sinon/download/sinon-1.17.7.tgz", 194 | "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=", 195 | "dev": true, 196 | "requires": { 197 | "formatio": "1.1.1", 198 | "lolex": "1.3.2", 199 | "samsam": "1.1.2", 200 | "util": ">=0.10.3 <1" 201 | } 202 | }, 203 | "supports-color": { 204 | "version": "1.2.0", 205 | "resolved": "https://registry.npm.taobao.org/supports-color/download/supports-color-1.2.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fsupports-color%2Fdownload%2Fsupports-color-1.2.0.tgz", 206 | "integrity": "sha1-/x7R5hFp0Gs88tWI4YixjYhH4X4=", 207 | "dev": true 208 | }, 209 | "to-iso-string": { 210 | "version": "0.0.2", 211 | "resolved": "https://registry.npm.taobao.org/to-iso-string/download/to-iso-string-0.0.2.tgz", 212 | "integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=", 213 | "dev": true 214 | }, 215 | "underscore": { 216 | "version": "1.8.3", 217 | "resolved": "https://registry.npm.taobao.org/underscore/download/underscore-1.8.3.tgz?cache=0&sync_timestamp=1578351586223&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Funderscore%2Fdownload%2Funderscore-1.8.3.tgz", 218 | "integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI=", 219 | "dev": true 220 | }, 221 | "util": { 222 | "version": "0.12.2", 223 | "resolved": "https://registry.npm.taobao.org/util/download/util-0.12.2.tgz?cache=0&sync_timestamp=1582534720131&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Futil%2Fdownload%2Futil-0.12.2.tgz", 224 | "integrity": "sha1-VK22NMnnx0hwevK/Wox6tkDLuis=", 225 | "dev": true, 226 | "requires": { 227 | "inherits": "^2.0.3", 228 | "is-arguments": "^1.0.4", 229 | "is-generator-function": "^1.0.7", 230 | "safe-buffer": "^5.1.2" 231 | } 232 | } 233 | } 234 | } 235 | -------------------------------------------------------------------------------- /gulp-demo/dist/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | my 3d album 9 | 10 | 11 |
12 |
13 | 54 | 95 | 136 | 177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /gulp-demo/src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | my 3d album 11 | 12 | 13 |
14 |
15 | 56 | 97 | 138 | 179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 | 250 | 251 | 252 | 253 | 254 | 255 | -------------------------------------------------------------------------------- /cloneDeep/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "clonedeep", 3 | "version": "1.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "abab": { 8 | "version": "2.0.1", 9 | "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.1.tgz", 10 | "integrity": "sha512-1zSbbCuoIjafKZ3mblY5ikvAb0ODUbqBnFuUb7f6uLeQhhGJ0vEV4ntmtxKLT2WgXCO94E07BjunsIw1jOMPZw==" 11 | }, 12 | "acorn": { 13 | "version": "6.4.2", 14 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.2.tgz", 15 | "integrity": "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==" 16 | }, 17 | "acorn-globals": { 18 | "version": "4.3.4", 19 | "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.4.tgz", 20 | "integrity": "sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A==", 21 | "requires": { 22 | "acorn": "^6.0.1", 23 | "acorn-walk": "^6.0.1" 24 | } 25 | }, 26 | "acorn-walk": { 27 | "version": "6.2.0", 28 | "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.2.0.tgz", 29 | "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==" 30 | }, 31 | "ajv": { 32 | "version": "6.10.2", 33 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", 34 | "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", 35 | "requires": { 36 | "fast-deep-equal": "^2.0.1", 37 | "fast-json-stable-stringify": "^2.0.0", 38 | "json-schema-traverse": "^0.4.1", 39 | "uri-js": "^4.2.2" 40 | } 41 | }, 42 | "array-equal": { 43 | "version": "1.0.0", 44 | "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", 45 | "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" 46 | }, 47 | "asn1": { 48 | "version": "0.2.4", 49 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", 50 | "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", 51 | "requires": { 52 | "safer-buffer": "~2.1.0" 53 | } 54 | }, 55 | "assert-plus": { 56 | "version": "1.0.0", 57 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 58 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 59 | }, 60 | "async-limiter": { 61 | "version": "1.0.1", 62 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", 63 | "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" 64 | }, 65 | "asynckit": { 66 | "version": "0.4.0", 67 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 68 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 69 | }, 70 | "aws-sign2": { 71 | "version": "0.7.0", 72 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 73 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 74 | }, 75 | "aws4": { 76 | "version": "1.8.0", 77 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", 78 | "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" 79 | }, 80 | "bcrypt-pbkdf": { 81 | "version": "1.0.2", 82 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", 83 | "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", 84 | "requires": { 85 | "tweetnacl": "^0.14.3" 86 | } 87 | }, 88 | "browser-process-hrtime": { 89 | "version": "0.1.3", 90 | "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", 91 | "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" 92 | }, 93 | "caseless": { 94 | "version": "0.12.0", 95 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 96 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 97 | }, 98 | "combined-stream": { 99 | "version": "1.0.8", 100 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 101 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 102 | "requires": { 103 | "delayed-stream": "~1.0.0" 104 | } 105 | }, 106 | "core-util-is": { 107 | "version": "1.0.2", 108 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 109 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 110 | }, 111 | "cssom": { 112 | "version": "0.3.8", 113 | "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", 114 | "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==" 115 | }, 116 | "cssstyle": { 117 | "version": "1.4.0", 118 | "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.4.0.tgz", 119 | "integrity": "sha512-GBrLZYZ4X4x6/QEoBnIrqb8B/f5l4+8me2dkom/j1Gtbxy0kBv6OGzKuAsGM75bkGwGAFkt56Iwg28S3XTZgSA==", 120 | "requires": { 121 | "cssom": "0.3.x" 122 | } 123 | }, 124 | "dashdash": { 125 | "version": "1.14.1", 126 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 127 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 128 | "requires": { 129 | "assert-plus": "^1.0.0" 130 | } 131 | }, 132 | "data-urls": { 133 | "version": "1.1.0", 134 | "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", 135 | "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", 136 | "requires": { 137 | "abab": "^2.0.0", 138 | "whatwg-mimetype": "^2.2.0", 139 | "whatwg-url": "^7.0.0" 140 | } 141 | }, 142 | "deep-is": { 143 | "version": "0.1.3", 144 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 145 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" 146 | }, 147 | "delayed-stream": { 148 | "version": "1.0.0", 149 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 150 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 151 | }, 152 | "domexception": { 153 | "version": "1.0.1", 154 | "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", 155 | "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", 156 | "requires": { 157 | "webidl-conversions": "^4.0.2" 158 | } 159 | }, 160 | "ecc-jsbn": { 161 | "version": "0.1.2", 162 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", 163 | "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", 164 | "requires": { 165 | "jsbn": "~0.1.0", 166 | "safer-buffer": "^2.1.0" 167 | } 168 | }, 169 | "escodegen": { 170 | "version": "1.12.0", 171 | "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.12.0.tgz", 172 | "integrity": "sha512-TuA+EhsanGcme5T3R0L80u4t8CpbXQjegRmf7+FPTJrtCTErXFeelblRgHQa1FofEzqYYJmJ/OqjTwREp9qgmg==", 173 | "requires": { 174 | "esprima": "^3.1.3", 175 | "estraverse": "^4.2.0", 176 | "esutils": "^2.0.2", 177 | "optionator": "^0.8.1", 178 | "source-map": "~0.6.1" 179 | } 180 | }, 181 | "esprima": { 182 | "version": "3.1.3", 183 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", 184 | "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" 185 | }, 186 | "estraverse": { 187 | "version": "4.3.0", 188 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 189 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" 190 | }, 191 | "esutils": { 192 | "version": "2.0.3", 193 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", 194 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" 195 | }, 196 | "extend": { 197 | "version": "3.0.2", 198 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 199 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 200 | }, 201 | "extsprintf": { 202 | "version": "1.3.0", 203 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 204 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 205 | }, 206 | "fast-deep-equal": { 207 | "version": "2.0.1", 208 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", 209 | "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" 210 | }, 211 | "fast-json-stable-stringify": { 212 | "version": "2.0.0", 213 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 214 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 215 | }, 216 | "fast-levenshtein": { 217 | "version": "2.0.6", 218 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 219 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" 220 | }, 221 | "forever-agent": { 222 | "version": "0.6.1", 223 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 224 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 225 | }, 226 | "form-data": { 227 | "version": "2.3.3", 228 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", 229 | "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", 230 | "requires": { 231 | "asynckit": "^0.4.0", 232 | "combined-stream": "^1.0.6", 233 | "mime-types": "^2.1.12" 234 | } 235 | }, 236 | "getpass": { 237 | "version": "0.1.7", 238 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 239 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 240 | "requires": { 241 | "assert-plus": "^1.0.0" 242 | } 243 | }, 244 | "har-schema": { 245 | "version": "2.0.0", 246 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 247 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 248 | }, 249 | "har-validator": { 250 | "version": "5.1.3", 251 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", 252 | "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", 253 | "requires": { 254 | "ajv": "^6.5.5", 255 | "har-schema": "^2.0.0" 256 | } 257 | }, 258 | "html-encoding-sniffer": { 259 | "version": "1.0.2", 260 | "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", 261 | "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", 262 | "requires": { 263 | "whatwg-encoding": "^1.0.1" 264 | } 265 | }, 266 | "http-signature": { 267 | "version": "1.2.0", 268 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 269 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 270 | "requires": { 271 | "assert-plus": "^1.0.0", 272 | "jsprim": "^1.2.2", 273 | "sshpk": "^1.7.0" 274 | } 275 | }, 276 | "iconv-lite": { 277 | "version": "0.4.24", 278 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 279 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 280 | "requires": { 281 | "safer-buffer": ">= 2.1.2 < 3" 282 | } 283 | }, 284 | "ip-regex": { 285 | "version": "2.1.0", 286 | "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", 287 | "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=" 288 | }, 289 | "is-typedarray": { 290 | "version": "1.0.0", 291 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 292 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 293 | }, 294 | "isstream": { 295 | "version": "0.1.2", 296 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 297 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 298 | }, 299 | "jquery": { 300 | "version": "3.5.0", 301 | "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.0.tgz", 302 | "integrity": "sha512-Xb7SVYMvygPxbFMpTFQiHh1J7HClEaThguL15N/Gg37Lri/qKyhRGZYzHRyLH8Stq3Aow0LsHO2O2ci86fCrNQ==" 303 | }, 304 | "jsbn": { 305 | "version": "0.1.1", 306 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 307 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" 308 | }, 309 | "jsdom": { 310 | "version": "15.1.1", 311 | "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-15.1.1.tgz", 312 | "integrity": "sha512-cQZRBB33arrDAeCrAEWn1U3SvrvC8XysBua9Oqg1yWrsY/gYcusloJC3RZJXuY5eehSCmws8f2YeliCqGSkrtQ==", 313 | "requires": { 314 | "abab": "^2.0.0", 315 | "acorn": "^6.1.1", 316 | "acorn-globals": "^4.3.2", 317 | "array-equal": "^1.0.0", 318 | "cssom": "^0.3.6", 319 | "cssstyle": "^1.2.2", 320 | "data-urls": "^1.1.0", 321 | "domexception": "^1.0.1", 322 | "escodegen": "^1.11.1", 323 | "html-encoding-sniffer": "^1.0.2", 324 | "nwsapi": "^2.1.4", 325 | "parse5": "5.1.0", 326 | "pn": "^1.1.0", 327 | "request": "^2.88.0", 328 | "request-promise-native": "^1.0.7", 329 | "saxes": "^3.1.9", 330 | "symbol-tree": "^3.2.2", 331 | "tough-cookie": "^3.0.1", 332 | "w3c-hr-time": "^1.0.1", 333 | "w3c-xmlserializer": "^1.1.2", 334 | "webidl-conversions": "^4.0.2", 335 | "whatwg-encoding": "^1.0.5", 336 | "whatwg-mimetype": "^2.3.0", 337 | "whatwg-url": "^7.0.0", 338 | "ws": "^7.0.0", 339 | "xml-name-validator": "^3.0.0" 340 | } 341 | }, 342 | "json-schema": { 343 | "version": "0.2.3", 344 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 345 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 346 | }, 347 | "json-schema-traverse": { 348 | "version": "0.4.1", 349 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 350 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" 351 | }, 352 | "json-stringify-safe": { 353 | "version": "5.0.1", 354 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 355 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 356 | }, 357 | "jsprim": { 358 | "version": "1.4.1", 359 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 360 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 361 | "requires": { 362 | "assert-plus": "1.0.0", 363 | "extsprintf": "1.3.0", 364 | "json-schema": "0.2.3", 365 | "verror": "1.10.0" 366 | } 367 | }, 368 | "levn": { 369 | "version": "0.3.0", 370 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 371 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 372 | "requires": { 373 | "prelude-ls": "~1.1.2", 374 | "type-check": "~0.3.2" 375 | } 376 | }, 377 | "loadsh": { 378 | "version": "0.0.4", 379 | "resolved": "https://registry.npmjs.org/loadsh/-/loadsh-0.0.4.tgz", 380 | "integrity": "sha512-U+wLL8InpfRalWrr+0SuhWgGt10M4OyAk6G8xCYo2rwpiHtxZkWiFpjei0vO463ghW8LPCdhqQxXlMy2qicAEw==" 381 | }, 382 | "lodash": { 383 | "version": "4.17.19", 384 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", 385 | "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" 386 | }, 387 | "lodash.sortby": { 388 | "version": "4.7.0", 389 | "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", 390 | "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" 391 | }, 392 | "mime-db": { 393 | "version": "1.40.0", 394 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", 395 | "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" 396 | }, 397 | "mime-types": { 398 | "version": "2.1.24", 399 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", 400 | "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", 401 | "requires": { 402 | "mime-db": "1.40.0" 403 | } 404 | }, 405 | "nwsapi": { 406 | "version": "2.1.4", 407 | "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", 408 | "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==" 409 | }, 410 | "oauth-sign": { 411 | "version": "0.9.0", 412 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", 413 | "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" 414 | }, 415 | "optionator": { 416 | "version": "0.8.2", 417 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", 418 | "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", 419 | "requires": { 420 | "deep-is": "~0.1.3", 421 | "fast-levenshtein": "~2.0.4", 422 | "levn": "~0.3.0", 423 | "prelude-ls": "~1.1.2", 424 | "type-check": "~0.3.2", 425 | "wordwrap": "~1.0.0" 426 | } 427 | }, 428 | "parse5": { 429 | "version": "5.1.0", 430 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", 431 | "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==" 432 | }, 433 | "performance-now": { 434 | "version": "2.1.0", 435 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 436 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 437 | }, 438 | "pn": { 439 | "version": "1.1.0", 440 | "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", 441 | "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" 442 | }, 443 | "prelude-ls": { 444 | "version": "1.1.2", 445 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 446 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" 447 | }, 448 | "psl": { 449 | "version": "1.4.0", 450 | "resolved": "https://registry.npmjs.org/psl/-/psl-1.4.0.tgz", 451 | "integrity": "sha512-HZzqCGPecFLyoRj5HLfuDSKYTJkAfB5thKBIkRHtGjWwY7p1dAyveIbXIq4tO0KYfDF2tHqPUgY9SDnGm00uFw==" 452 | }, 453 | "punycode": { 454 | "version": "2.1.1", 455 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 456 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" 457 | }, 458 | "qs": { 459 | "version": "6.5.2", 460 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", 461 | "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" 462 | }, 463 | "request": { 464 | "version": "2.88.0", 465 | "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", 466 | "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", 467 | "requires": { 468 | "aws-sign2": "~0.7.0", 469 | "aws4": "^1.8.0", 470 | "caseless": "~0.12.0", 471 | "combined-stream": "~1.0.6", 472 | "extend": "~3.0.2", 473 | "forever-agent": "~0.6.1", 474 | "form-data": "~2.3.2", 475 | "har-validator": "~5.1.0", 476 | "http-signature": "~1.2.0", 477 | "is-typedarray": "~1.0.0", 478 | "isstream": "~0.1.2", 479 | "json-stringify-safe": "~5.0.1", 480 | "mime-types": "~2.1.19", 481 | "oauth-sign": "~0.9.0", 482 | "performance-now": "^2.1.0", 483 | "qs": "~6.5.2", 484 | "safe-buffer": "^5.1.2", 485 | "tough-cookie": "~2.4.3", 486 | "tunnel-agent": "^0.6.0", 487 | "uuid": "^3.3.2" 488 | }, 489 | "dependencies": { 490 | "punycode": { 491 | "version": "1.4.1", 492 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 493 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 494 | }, 495 | "tough-cookie": { 496 | "version": "2.4.3", 497 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", 498 | "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", 499 | "requires": { 500 | "psl": "^1.1.24", 501 | "punycode": "^1.4.1" 502 | } 503 | } 504 | } 505 | }, 506 | "request-promise-core": { 507 | "version": "1.1.2", 508 | "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", 509 | "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", 510 | "requires": { 511 | "lodash": "^4.17.11" 512 | } 513 | }, 514 | "request-promise-native": { 515 | "version": "1.0.7", 516 | "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", 517 | "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", 518 | "requires": { 519 | "request-promise-core": "1.1.2", 520 | "stealthy-require": "^1.1.1", 521 | "tough-cookie": "^2.3.3" 522 | }, 523 | "dependencies": { 524 | "tough-cookie": { 525 | "version": "2.5.0", 526 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", 527 | "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", 528 | "requires": { 529 | "psl": "^1.1.28", 530 | "punycode": "^2.1.1" 531 | } 532 | } 533 | } 534 | }, 535 | "safe-buffer": { 536 | "version": "5.2.0", 537 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", 538 | "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" 539 | }, 540 | "safer-buffer": { 541 | "version": "2.1.2", 542 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 543 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" 544 | }, 545 | "saxes": { 546 | "version": "3.1.11", 547 | "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz", 548 | "integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==", 549 | "requires": { 550 | "xmlchars": "^2.1.1" 551 | } 552 | }, 553 | "source-map": { 554 | "version": "0.6.1", 555 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 556 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 557 | "optional": true 558 | }, 559 | "sshpk": { 560 | "version": "1.16.1", 561 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", 562 | "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", 563 | "requires": { 564 | "asn1": "~0.2.3", 565 | "assert-plus": "^1.0.0", 566 | "bcrypt-pbkdf": "^1.0.0", 567 | "dashdash": "^1.12.0", 568 | "ecc-jsbn": "~0.1.1", 569 | "getpass": "^0.1.1", 570 | "jsbn": "~0.1.0", 571 | "safer-buffer": "^2.0.2", 572 | "tweetnacl": "~0.14.0" 573 | } 574 | }, 575 | "stealthy-require": { 576 | "version": "1.1.1", 577 | "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", 578 | "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" 579 | }, 580 | "symbol-tree": { 581 | "version": "3.2.4", 582 | "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", 583 | "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==" 584 | }, 585 | "tough-cookie": { 586 | "version": "3.0.1", 587 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-3.0.1.tgz", 588 | "integrity": "sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg==", 589 | "requires": { 590 | "ip-regex": "^2.1.0", 591 | "psl": "^1.1.28", 592 | "punycode": "^2.1.1" 593 | } 594 | }, 595 | "tr46": { 596 | "version": "1.0.1", 597 | "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", 598 | "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", 599 | "requires": { 600 | "punycode": "^2.1.0" 601 | } 602 | }, 603 | "tunnel-agent": { 604 | "version": "0.6.0", 605 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 606 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 607 | "requires": { 608 | "safe-buffer": "^5.0.1" 609 | } 610 | }, 611 | "tweetnacl": { 612 | "version": "0.14.5", 613 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 614 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" 615 | }, 616 | "type-check": { 617 | "version": "0.3.2", 618 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 619 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 620 | "requires": { 621 | "prelude-ls": "~1.1.2" 622 | } 623 | }, 624 | "uri-js": { 625 | "version": "4.2.2", 626 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 627 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 628 | "requires": { 629 | "punycode": "^2.1.0" 630 | } 631 | }, 632 | "uuid": { 633 | "version": "3.3.3", 634 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.3.tgz", 635 | "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" 636 | }, 637 | "verror": { 638 | "version": "1.10.0", 639 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 640 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 641 | "requires": { 642 | "assert-plus": "^1.0.0", 643 | "core-util-is": "1.0.2", 644 | "extsprintf": "^1.2.0" 645 | } 646 | }, 647 | "w3c-hr-time": { 648 | "version": "1.0.1", 649 | "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", 650 | "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", 651 | "requires": { 652 | "browser-process-hrtime": "^0.1.2" 653 | } 654 | }, 655 | "w3c-xmlserializer": { 656 | "version": "1.1.2", 657 | "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", 658 | "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", 659 | "requires": { 660 | "domexception": "^1.0.1", 661 | "webidl-conversions": "^4.0.2", 662 | "xml-name-validator": "^3.0.0" 663 | } 664 | }, 665 | "webidl-conversions": { 666 | "version": "4.0.2", 667 | "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", 668 | "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" 669 | }, 670 | "whatwg-encoding": { 671 | "version": "1.0.5", 672 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", 673 | "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", 674 | "requires": { 675 | "iconv-lite": "0.4.24" 676 | } 677 | }, 678 | "whatwg-mimetype": { 679 | "version": "2.3.0", 680 | "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", 681 | "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" 682 | }, 683 | "whatwg-url": { 684 | "version": "7.0.0", 685 | "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", 686 | "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", 687 | "requires": { 688 | "lodash.sortby": "^4.7.0", 689 | "tr46": "^1.0.1", 690 | "webidl-conversions": "^4.0.2" 691 | } 692 | }, 693 | "wordwrap": { 694 | "version": "1.0.0", 695 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", 696 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" 697 | }, 698 | "ws": { 699 | "version": "7.1.2", 700 | "resolved": "https://registry.npmjs.org/ws/-/ws-7.1.2.tgz", 701 | "integrity": "sha512-gftXq3XI81cJCgkUiAVixA0raD9IVmXqsylCrjRygw4+UOOGzPoxnQ6r/CnVL9i+mDncJo94tSkyrtuuQVBmrg==", 702 | "requires": { 703 | "async-limiter": "^1.0.0" 704 | } 705 | }, 706 | "xml-name-validator": { 707 | "version": "3.0.0", 708 | "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", 709 | "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" 710 | }, 711 | "xmlchars": { 712 | "version": "2.2.0", 713 | "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", 714 | "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==" 715 | } 716 | } 717 | } 718 | --------------------------------------------------------------------------------